批处理脚本:验证日期输入

时间:2013-12-06 01:00:56

标签: windows validation date batch-file

我有一个批处理文件,用于为客户创建新的项目文件夹,引导用户完成创建过程,并将相应的文件和文件夹添加到中心位置。我需要添加一个输入部分,以便他们可以输入日期(不总是当前日期),它包含在文件的命名中。

我有这个问题,而且我已经找到了高低,找不到我的答案,就是我需要虚拟证明日期输入。我希望用户以MM-DD-YYYY格式输入日期,包括破折号。然后需要将其格式化为YYYY-MM-DD。它需要足够智能,以迫使用户使用所需的MM-DD-YYYY格式;必须是数字和短划线,没有斜线,正确数量的字符等等。

我一直无法找到任何接近甚至遥远的地方让我到达我需要的地方所以我在这方面要求那些令人敬畏的天才在这方面提供帮助,因为它正在把我推向一堵墙。下面是我的脚本代码。我需要在输入作业类型后立即输入此输入。 "Please insert date (MM-DD-YYYY format): "

@echo off
setlocal EnableDelayedExpansion
set version=7.95
set projectpath="P:"
set workbookpath="\\server2\Documents\Blanks (DO NOT EDIT)\dryingworkbook_v3r75.xls"
set questions="\\server2\Documents\Blanks (DO NOT EDIT)\Abatement and Mold Questions.txt"
set notes="\\server2\Documents\Blanks (DO NOT EDIT)\Job Notes.docx"
set info="\\server2\Documents\Blanks (DO NOT EDIT)\Job Information.docx"
set bizname=1

ECHO =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
ECHO =  Welcome to SERVPRO Project Creation Wizard v%version%  =
ECHO =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
ECHO.

:sof
ECHO.
ECHO Is this new project for a Residential or Commercial job?
:loopJobType
SET /P jobtype=Enter [r] for Residential or [c] for Commercial:  
ECHO.
IF "%jobtype%" == "r" GOTO :loopResidential
IF "%jobtype%" == "R" GOTO :loopResidential
IF "%jobtype%" == "c" GOTO :loopCommercial
IF "%jobtype%" == "C" GOTO :loopCommercial
GOTO :loopJobType

:loopResidential
ECHO You have chosen to create a new Residential job project.
ECHO.
set type=1
GOTO :loopFirstName

:loopCommercial
ECHO You have chosen to create a new Commercial job project.
ECHO.
set type=2
SET /p bizname=Please enter the business name:  
ECHO.
IF "%bizname%"=="" GOTO :loopCommercial

:loopFirstName
SET /P FirstName=Please enter the insured's first name:  
IF "%FirstName%"=="" GOTO :loopFirstName
call :format FirstName

:loopLastName
ECHO.
SET /P LastName= Please enter the insured's last name:  
IF "%LastName%"=="" GOTO :loopLastName
call :format LastName
SET FullName=%LastName%, %FirstName%
SET FullBizName=%bizname% (%FullName%)
goto :ConfirmProject

:format
set Name=!%1!
set Head=%Name:~0,1%
set Tail=%Name:~1%
for %%a in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do set Head=!Head:%%a=%%a!
for %%a in (a b c d e f g h i j k l m n o p q r s t u v w x y z) do set Tail=!Tail:%%a=%%a!
set %1=%Head%%Tail%
GOTO :eof

:ConfirmProject
ECHO.
IF "%type%" == "1" SET /P yesno=Are you sure you want to add "%FullName%" to the Project directory? [y/n]  
IF "%type%" == "2" SET /P yesno=Are you sure you want to add "%FullBizName%" to the Project directory? [y/n]  
IF "%yesno%" == "y" GOTO :CreateProject
IF "%yesno%" == "Y" GOTO :CreateProject
IF "%yesno%" == "n" GOTO :sof
IF "%yesno%" == "N" GOTO :sof
GOTO :ConfirmProject

:CreateProject
IF "%type%" == "1" SET ProjectName=%FullName%
IF "%type%" == "2" SET ProjectName=%FullBizName%

:: Create a folder containing a new project.
mkdir "%projectpath%\%ProjectName%"
ECHO.
ECHO.
ECHO Creating a Project directory for "%ProjectName%" ...

:: Create a folder within said project that will contain job documents.
ECHO Creating a Documents directory for "%ProjectName%" ...
mkdir "%projectpath%\%ProjectName%\Documents"
:: (Taken out of use 7-15-13) ECHO Adding a Job Information file for "%ProjectName%" ...
:: (Taken out of use 7-15-13) copy /-Y %info% "%projectpath%\%ProjectName%\Documents\Job Information - %ProjectName%.docx"
ECHO Documents directory creation for "%ProjectName%" finished ...

:: Create a folder within said project that will contain drying workbook(s).
ECHO Creating a Drying Workbook directory for "%ProjectName%" ...
mkdir "%projectpath%\%ProjectName%\Drying Workbooks"

:: Copy a new blank workbook to the project workbook directory and give it the proper name.
ECHO Adding a Drying Workbook for "%ProjectName%" ...
copy /-Y %workbookpath% "%projectpath%\%ProjectName%\Drying Workbooks\DRY 1_%ProjectName%.xls"
ECHO Adding an Abatement and Mold Questions file for "%ProjectName%" ...
copy /-Y %questions% "%projectpath%\%ProjectName%\Drying Workbooks\Abatement and Mold Questions.txt"
ECHO Drying Workbook directory creation for "%ProjectName%" finished ...

:: Create a folder within said project that will contain original photos.
ECHO Creating a Photos directory for "%ProjectName%" ...
mkdir "%projectpath%\%ProjectName%\"Photos

:: Create a folder within said project photo folder that will contain resized photos.
mkdir "%projectpath%\%ProjectName%\Photos\Resized"
mkdir "%projectpath%\%ProjectName%\Photos\Upload"
ECHO Photos directory creation for "%ProjectName%" finished ...

:: Add in Job Notes file.
ECHO Adding a Job Notes files for "%ProjectName%" ...
copy /-Y %notes% "%projectpath%\%ProjectName%\Job Notes - %ProjectName%.docx"

::  Log the creation of the project.
FOR /F "TOKENS=1* DELIMS= " %%A IN ('DATE/T') DO SET CDATE=%%B
For /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set date=%%a%%b%%c)
echo off >  "%projectpath%\Logs\%ProjectName% - [Project Created %date% by %computername%].txt"
ECHO Logging "%ProjectName%" creation date and time...
ECHO Project directory creation for "%ProjectName%" finished ...
GOTO :OpenProject

:OpenProject
:: Ask if the project should be opened now.  If so open and close script, else close script.
set /p reply=Do you want to open the "%ProjectName%" project now? [y/n]
if "%reply%" == "y" %SystemRoot%\explorer.exe "%projectpath%\%ProjectName%"
IF "%yesno%" == "Y" %SystemRoot%\explorer.exe "%projectpath%\%ProjectName%"
GOTO :eof
IF "%yesno%" == "n" GOTO :No
IF "%yesno%" == "N" GOTO :No
exit

:No
ECHO.
ECHO.
ECHO You have successfully created a new project for %ProjectName%.
ECHO.
ECHO Press any key to exit . . .
PAUSE>NUL

:eof

6 个答案:

答案 0 :(得分:4)

您可以使用findstr命令轻松检查字符串是否有效。

set /p date= Please insert date (MM-DD-YYYY format):
echo %date%| findstr /r "^[0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9]$">nul
if errorlevel 1 (
    echo invalid date
)
pause

(^表示行的开头,而$表示行的结尾。)

现在,为了将MM-DD-YYYY重新格式化为YYYY-MM-DD,您可以拆分字符串而不是重新组合它。由于它是一种固定的格式,这也不是太难:

set yyyy=%date:~6,4%
set mm=%date:~0,2%
set dd=%date:~3,2%
set newDate=%yyyy%-%mm%-%dd%
echo %newDate%

每个命令中的第一个数字类似于剪切字符串的位置。 第二个数字类似于子字符串的长度。

答案 1 :(得分:4)

下面的批处理文件检查插入的日期是否具有正确的格式,它表示有效日期,即每月有正确的天数,即使是2月份的飞跃年!

@echo off
setlocal EnableDelayedExpansion

set i=0
for %%a in (31 28 31 30 31 30 31 31 30 31 30 31) do (
   set /A i+=1
   set dpm[!i!]=%%a
)

set /P "inDate=Please insert date (MM-DD-YYYY format): "
if "%inDate:~2,1%%inDate:~5,1%" neq "--" goto invalidDate
for /F "tokens=1-3 delims=-" %%a in ("%inDate%") do set "MM=%%a" & set "DD=%%b" & set "YYYY=%%c"
ver > NUL
set /A month=1%MM%-100, day=1%DD%-100, year=1%YYYY%-10000, leap=year%%4  2>NUL
if errorlevel 1 goto invalidDate
if not defined dpm[%month%] goto invalidDate
if %leap% equ 0 set dpm[2]=29
if %day% gtr !dpm[%month%]! goto invalidDate
if %day% lss 1 goto invalidDate
echo Date correct: %YYYY%-%MM%-%DD%
goto :EOF

:invalidDate
echo Bad date

答案 2 :(得分:1)

我做了一个函数:测试日期的getdate尝试它; 它将测试分隔符是否正确,thr月份和日期的值范围 如果值为NUM。

@ECHO OFF
setlocal enabledelayedexpansion

:GetDate
set /p $D=Enter a date (MM-DD-YYYY) :

set $separate=%$d:~2,1% %$d:~5,1%

for %%a in (%$separate%) do (if "%%a" neq "-" (echo Wrong Separator : %%a
                                               pause
                                               goto:Getdate))


set $D=%$D:-= %
set $c=1

for %%a in (%$d%) do (call:test !$c! %%a
                      set /a $c+=1)

if !$c!==4 set $DateOK=%$month%-%$day%-%$Year%
echo This DATE IS OK %$dateOK%
exit /b

:test
if %1 equ 1 (echo %2 | findstr [0-9][0-9]
             if errorlevel 1 (echo Unvalid value for Month [NOT NUM]: %2
                              pause
                              goto:getdate)

             if %2 GTR 12 (echo Unvalid value for Month [VALUR RANGE +]: %2
                                pause
                                goto:getdate)
              if %2 LSS 1 (echo Unvalid value for Month [VALUR RANGE -]: %2
                                pause
                                goto:getdate)
              set $month=%2) 



if %1==2  (echo %2 | findstr [0-9][0-9]
           if errorlevel 1 (echo Unvalid value for Day [NOT NUM]: %2
                            pause
                            goto:getdate)
           if %2 GTR 31 (echo Unvalid value for Day [VALUR RANGE +] : %2
                              pause
                              goto:getdate)
           if %2 LSS 01 (echo Unvalid value for Day [VALUE RANGE -]: %2
                              pause
                              goto:getdate)
           set $day=%2)


if %1==3  (echo %2 | findstr [0-9][0-9][0-9][0-9]
           if errorlevel 1 (echo Unvalid value for Year [NOT NUM] : %2
                            pause
                            goto:getdate)
         set $Year=%2)

答案 3 :(得分:1)

@ECHO OFF
SETLOCAL enabledelayedexpansion
CALL :getverdate
ECHO DATE %indate% is OK.
GOTO :EOF
::
:: Get and verify date in format mm-dd-yyyy; reformat as yyyy-mmm-dd
::
:regetdate
ECHO "%indate%" is not in format "MM-DD-YYYY" or is invalid
:getverdate
SET /p indate="Please insert date (MM-DD-YYYY format): "
IF NOT "%indate:~2,1%%indate:~5,1%"=="--" GOTO regetdate
SET checkdate=9%indate:-=%
IF NOT "%checkdate:~8%"=="%checkdate:~8,1%" GOTO regetdate
FOR %%a IN (0 1 2 3 4 5 6 7 8 9) DO SET checkdate=!checkdate:%%a=!
IF DEFINED checkdate GOTO regetdate
IF %indate:~3,2%==00 GOTO regetdate
FOR %%i IN (01:31 02:29 03:31 04:30 05:31 06:30 07:31 08:31 09:30 10:31 11:30 12:31) DO (
 FOR /f "tokens=1,2delims=:" %%j IN ("%%i") DO IF %%j==%indate:~0,2% if "%%k" geq "%indate:~3,2%" GOTO goodday 
)
GOTO regetdate
:goodday
IF "%indate:~-4%" geq "1980" IF "%indate:~-4%" leq "2099" GOTO goodyear
GOTO regetdate
:goodyear
SET /a checkdate=%indate:~-4% %% 4
IF "%indate:~0,2%%indate:~3,2%"=="0229" IF %checkdate% neq 0 GOTO regetdate
SET indate=%indate:~-4%-%indate:~0,2%-%indate:~3,2%
GOTO :eof

这是另一个“获取并验证日期”例程。

请注意,在您的代码中,您不应该设置名为date的变量。 %date%将返回当前日期 - 它是由CMD控制的“神奇变量”。其他此类变量包括%time%%random%%errorlevel%。设置任何这些覆盖系统建立的值。

答案 4 :(得分:0)

您可以向用户显示三个提示 - 年,月,日。

set /p y="Please enter year (YYYY): "
set /p m="Please enter month (MM): "
set /p d="Please enter day (DD): "
set date=%y%-%m%-%d%

如果您想验证输入的长度,请执行以下操作:

if [%y:~4%] NEQ [] echo year entered incorrectly & goto :getDate

您可以假设%y%大于四个字符 - 即如果%y:~4%不为空 - 它输入错误(请参阅Dos Tips on string manipulation)。同一本金适用于日期和月份,但它们应为两个字符 显然,对于该示例,您需要在用户输入之前添加标签:getDate

答案 5 :(得分:0)

您可以对所有类型的格式化输入使用ReadFormattedLine子例程。例如,下面的命令以日期格式读取3个数字;例程只接受数字,插入连字符并在读取最后一个数字后自动继续。如果用户删除字符,连字符也会自动删除。

call :ReadFormattedLine myDate="##-##-####" /M "Please insert date (MM-DD-YYYY format): "

这个子程序是用纯批处理编写的,所以它不需要任何额外的程序,它允许几个格式化的输入操作,如读取密码,将字母转换为大写等。您可以从Read a line with specific format下载ReadFormattedLine子程序。