Batch Script: Validate Date Input

后端 未结 6 1293
予麋鹿
予麋鹿 2020-12-21 06:39

I have a batch file that I use to create new project folders for clients that walks a user through the creation process and adds the appropriate files and folders to a centr

相关标签:
6条回答
  • 2020-12-21 07:01

    You may use ReadFormattedLine subroutine for all kind of formatted input. For example, the command below read 3 numbers in a date format; the routine just accept digits, insert the hyphens and continue automatically after read the last digit. If the user delete characters, the hyphens are also deleted automatically.

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

    This subroutine is written in pure Batch so it does not require any additional program, and it allows several formatted input operations, like read passwords, convert letters to uppercase, etc. You may download ReadFormattedLine subroutine from Read a line with specific format.

    0 讨论(0)
  • 2020-12-21 07:04

    You could present the user with three prompts - year, month, day.

    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 you would like to verify the length of the input something like:

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

    You can assume if %y% is greater than four characters - i.e. if %y:~4% is not null - that it has been entered incorrectly (see Dos Tips on string manipulation). The same principal applies for day and month, except they should be two characters.
    Obviously for that example you would need to add the label :getDate before the user input.

    0 讨论(0)
  • 2020-12-21 07:12

    I made a function :getdate who test the date try it; It will test if the separators are correct, the value range for thr month and the day and if the values are 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)
    
    0 讨论(0)
  • 2020-12-21 07:13

    The Batch file below check that the inserted date have the right format and that it represent a valid date, that is, that have the right number of days in each month, even for February on leap years!

    @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
    
    0 讨论(0)
  • 2020-12-21 07:17

    You can check whether your string is valid easily with the findstr command.

    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
    

    (^ means beginning of line, while $ stands for end of line.)

    Now for the reformatting MM-DD-YYYY into YYYY-MM-DD, you can split your string and than reassemble it. Since it's a fixed format, this isn't too hard either:

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

    The first number in each command resembles the position where the string will be cut. The second number resembles the length of the substring.

    0 讨论(0)
  • 2020-12-21 07:26
    @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
    

    Here's another 'get and validate date` routine.

    Note that in your code you should never set a variable called date. %date% will return the current date - it's a "magic variable" controlled by CMD. Other such variables include %time%, %random% and %errorlevel%. Setting any of these overrides the system-established value.

    0 讨论(0)
提交回复
热议问题