使用批处理文件

时间:2016-11-28 11:28:13

标签: validation batch-file cmd

使用批处理文件,我从用户那里获取日期。 现在,我想验证日期是否为YYYY-MM-DD格式。

我一直在寻找,但我没有在这里得到一些东西: 在某个地方找到了这个:

set /p startDate=Start Date [YYYY-MM-DD]: 
if "%startDate:~2,1%%startDate:~5,1%" neq "--" goto invalidDate
for /f "tokens=2 delims==" %%I in ("%startDate%") do set datetime=%%I
ver > NUL
set /A month=1%MM%-100, day=1%DD%-100, year=1%YYYY%-10000, leap=year%%4
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%

这些是什么: 〜2, 1 %%变量:〜5, %%,  在cmd帮助中,我发现单个%但不是双%%

另外,

set /A month=1%MM%-100, day=1%DD%-100, year=1%YYYY%-10000, leap=year%%4

这实际上是做什么的。请问有人可以解释一下这个角色吗?

3 个答案:

答案 0 :(得分:3)

有时会使用Double %(虽然我不知道确切的目的; 我认为它是延迟扩展但是)但在你的情况下它只是两个连接使用的变量:

set foo=foo
set bar=bar
echo %foo%%bar%

- > foobar

它的另一个用途(至少在批处理文件中)是for循环中变量的声明和使用:for /l %%I in(1,1,5) do echo %%i。在命令提示符中,您只能编写%i 你发布的第二行对我来说没有任何意义,说实话...... 感谢Aacinis的评论,这对我来说很有意义!基本上完成的是:

变量为set,其/A算术项在前面添加1以再次减去它。例如:

set /a year=1%YYYY%-10000

- >将变量year的值设置为变量1YYYY - 10000的值。这样做(感谢Aacini再次解释)以防止带有前导零(例如08)的输入被解释为八进制值,其中这种情况会导致无效日期。请注意,如果您使用/a,则会有所不同:

set foo=1+1
set /a bar=1+1
echo foo %foo%
echo bar %bar%

接下来我们有另一个%%的案例,在这种情况下是模运算符。

如果愿意,模运算符将返回除法的其余部分。例子:

10 %% 2 = 0(你可以将10除以2而不休息)
11 %% 4 = 3(8乘4是2,其余8到11是3)

无论年份是闰年(值== 0)还是没有(值!= 0),我都会保存变量跳跃。然而,在检查闰年时你必须考虑的其他规则有点容易,但这不属于......

%startDate:~2,1%%startDate:~5,1%

将生成一个字符串,该字符串在第一个 2 之后带有 1 字符,而 1 在第一个 5之后 >人物。在您的情况下,您必须将其更改为~4,1~7,1,因为第5个和第8个字符是程序检查的破折号。

J.Baoby建议this link仔细研究。另外两个有用的帮助来源是DostipsSS64

随意提问:)

答案 1 :(得分:1)

您的程序肯定存在一些代码问题,但我将为您提供一种替代方法来检查使用少量XCOPY技巧的有效日期。它基本上使用XCOPY检查两个空文件夹以进行复制,但我们使用/ L选项,以便它不会实际复制任何内容。另一个技巧是,如果日期无效,它会在尝试复制之前抛出错误,我们可以使用它来重定向回问题以询问有效日期。

@echo off

:invalidDate
cls
set /p startDate=Start Date YYYY-MM-DD:

REM xcopy needs date in m-d-y format
for /f "tokens=1,2,3 delims=-" %%G in ("%startDate%") do set checkdate=%%H-%%I-%%G
set rand=%random%
md "dummy%rand%\empty%rand%"

xcopy /d:%checkdate% /t "dummy%rand%\empty%rand%" "dummy%rand%" >nul 2>&1 ||(
    rd /s /q "dummy%rand%" 
    goto invalidDate
    )

rd /s /q "dummy%rand%"
echo %startdate% is a valid date

pause

答案 2 :(得分:0)

好吧,如果你拿一个正常工作的代码,修改它,然后你问"为什么这段代码不起作用?",我认为答案是显而易见的......

这是original code你发现的地方":

@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

如果要将原始MM-DD-YYYY日期格式更改为YYYY-MM-DD,则必须更改以下行:

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"

......通过这些:

set /P "startDate=Start Date [YYYY-MM-DD]: "
if "%startDate:~4,1%%startDate:~7,1%" neq "--" goto invalidDate
for /F "tokens=1-3 delims=-" %%a in ("%startDate%") do set "YYYY=%%a" & set "MM=%%b" & set "DD=%%c"

this answer给出!dpm[%month%]!部分的进一步解释。我邀请你阅读这样一个答案并提出它,因为它只需要几个赞成就能达到100!的 ;)