批处理脚本:validationdateinput

我有一个batch file,用于为客户创build新的项目文件夹,让用户完成创build过程并将相应的文件和文件夹添加到中央位置。 我需要添加一个input部分,以便他们可以放入一个date(并非总是当前date),并将其包含在文件的命名中。

我有的问题,我已经高高在上,找不到我的答案,是我需要虚拟certificatedateinput。 我希望用户inputMM-DD-YYYY格式的date,包括破折号。 需要将其格式化为YYYY-MM-DD 。 它需要足够聪明,它迫使用户使用所需格式的MM-DD-YYYY ; 必须是数字和破折号,没有斜杠,适量的字符,等等。

我一直无法find任何接近的东西,甚至远远地把我带到我需要的地方,所以我要求那些真棒天才在这方面提供帮助,因为它正在把我推上一堵墙。 以下是我的脚本代码。 select作业types后,我需要这个input。 "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 (ABCDEFGHIJKLMNOPQRSTU VWXYZ) do set Head=!Head:%%a=%%a! for %%a in (abcdefghijklmnopqrstu vwxyz) 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 

下面的批处理文件检查插入的日期是否具有正确的格式并且它代表有效的日期,即每个月有适当的天数,即使在闰年的二月份也是如此!

 @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 

您可以使用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% 

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

我做了一个函数:getdate测试日期的人试一试; 它将测试分隔符是否正确,月份和日期的值范围以及值是否为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) 
 @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% 。 设置任何这些覆盖系统建立的值。

您可以向用户提供三个提示 – 年,月,日。

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

如果您想验证输入的长度,如:

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

你可以假设,如果%y%大于四个字符 – 即如果%y:〜4%不为空 – 输入不正确(请参阅Dos关于字符串操作的提示 )。 除了应该是两个字符之外,同一个委托人适用于日期和月份。
显然对于这个例子,你需要在用户输入之前添加标签:getDate

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

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

这个子程序是用纯批量编写的,所以它不需要任何额外的程序,它允许进行多种格式化的输入操作,比如读取密码,将字母转换为大写等等。你可以从Read行中下载ReadFormattedLine子程序。