Batch file 在批处理文件中计算上一个日期已停止

Batch file 在批处理文件中计算上一个日期已停止,batch-file,Batch File,这里有很多关于成批使用变量进行计算的问题,它们非常有用,但我还没有找到一个适合这个特定问题的问题。我要做的是让用户以MM-DD格式为他们必须定期执行的批处理任务输入日期。关键是,它从SQL表中提取选定日期前一天的文件。从SQL中提取数据没有问题,但我在计算上一个日期时遇到了一个问题。下面的代码片段经过简化以演示我遇到的问题,使用“ECHO”而不是“BCP”只是为了说明 SET /P DA=Input a two digit day: IF %DA% GEQ 2 SET /A Dmin=DA-1

这里有很多关于成批使用变量进行计算的问题,它们非常有用,但我还没有找到一个适合这个特定问题的问题。我要做的是让用户以MM-DD格式为他们必须定期执行的批处理任务输入日期。关键是,它从SQL表中提取选定日期前一天的文件。从SQL中提取数据没有问题,但我在计算上一个日期时遇到了一个问题。下面的代码片段经过简化以演示我遇到的问题,使用“ECHO”而不是“BCP”只是为了说明

SET /P DA=Input a two digit day: 
IF %DA% GEQ 2 SET /A Dmin=DA-1
IF %DA% LEQ 10 SET Dmin=0%Dmin%
ECHO You Input %DA%
ECHO Calc got %Dmin%
我需要两位数的格式,因为SQL命令的日期部分的格式是MM-DD-YYYY 这里的问题是,如果您输入的日期为02到07,它将按预期输出01到06,并且其行为也适用于10+的值。但是,如果用户输入“08”或“09”,它只输出“0”或什么也不输出(或者不管最后一个变量在08或09之前是什么,在执行时添加更多的0)


为什么会这样?08和09有什么特别之处导致了这种奇怪的行为?我如何修复它?

在构建这种类型的函数时,需要记住一些事情

  • 输入验证:测试用户输入并将其限制在适当的数字范围内
  • 删除前导零。如果尝试使用包含前导零的值执行计算,则需要执行的计算将失败
  • 将变量转换为相等的形式进行比较。
    • 在对数据执行转换计算之前,使用子字符串修改来提取信息并对其排序-当然,这需要您知道数据最初的格式,以决定需要对其进行哪些修改
在验证特定数值范围的输入时,可以使用如下方法:

@Echo Off
    SetLocal EnableDelayedExpansion
    :MM
    Set /p "MM=Enter Numeric value for MM:"
    For /L %%A in (1,1,12) Do (If "%%A"=="!MM!" Goto :DD)
    Goto :MM
    :DD
    Set /p "DD=Enter Numeric value for DD:"
    For /L %%A in (1,1,31) Do (If "%%A"=="!DD!" Goto :YYYY)
    Goto :DD
    :YYYY
    Set /p "YYYY=Enter Numeric value for YYYY:"
    For /L %%A in (1985,1,2100) Do (If "%%A"=="!YYYY!" Goto :Next)
    Goto :YYYY
    :Next
    REM Your Commands Here
    pause

从变量中删除前导零的方法是:

Set/A var=100%var%%%100

将日期转换为julian日期以用于比较的函数-尤其是在X天之前的场景中:

:ConvertJulian <DD> <MM> <YYYY> <resultVar>

REM DD and MM values MUST have leading zero's removed prior to being passed to this function as parameters

    Setlocal
    Set "Day=%1"
    Set "Month=%2"
    Set /a "MonthCv=( %Month% - 14 ) / 12"
    Set /a "YearCv=%3 + 4800"
    Set /a "Julian=1461 * ( %YearCv% + %MonthCv% ) / 4 + 367 * ( %Month% - 2 -12 * %MonthCv% ) / 12 - ( 3 * ( ( %YearCv% + %MonthCv% + 100 ) / 100 ) ) / 4 + %Day% - 32075"

    (
    Endlocal
    Set "%4=%Julian%"
    exit /b
    )
:朱利安
REM DD和MM值在作为参数传递到此函数之前,必须删除前导零
Setlocal
设置“日期=%1”
设置“月份=%2”
设置/a“月份=(%Month%-14)/12”
设置/a“YearCv=%3+4800”
设置/a“Julian=1461*(%YearCv%+%MonthCv%)/4+367*(%Month%-2-12*%MonthCv%)/12-(3*(%YearCv%+%MonthCv%+100)/100))/4+%Day%-32075”
(
端部
设置“%4=%Julian%”
退出/b
)

请参阅或了解一个实际示例

如果您使用了/正在使用类似的方法进行月份输入,那么当最终用户为
mm
输入
03
DD
输入
01
时会发生什么情况。仅出于这个原因,我建议您使用支持日期作为对象的编程工具。接下来我建议e是指在尝试将输入用于预期目的之前,确保输入与可能输入的格式和范围相匹配。我在前面的脚本中进行了验证,实际用户输入做了一些事情,我在两个关键方面受到限制,我必须使用批处理,并且最终输出必须有两位数字,即以下日期10必须有一个前导0。这是因为提示用户生成最终使用此信息的日期列表有三种方式。在MM-DD-YYYY中选择的日期列表,在减去一天后选择的日期列表,以及只接受格式为YYMMDD的日期的第三方应用程序。不启用前导0一位数的天数不是一个选项。我仍然坚持使用当前值,包括前导零,在第01天到第07天工作,而不是第08天和第09天。为什么这两天不同?与您的答案不同,它也不应该在第01-07天工作。在这种情况下,前导零可以保留在变量中,并在的本地环境中删除处理日期信息的子例程。或者,您可以使用以下命令为希望在DDMMYY中添加零的时间使用辅助变量:
如果“!Var:~,-1!”==”(设置“VarCopy=0!Var!”)
如果变量是一位数字,则上述命令将在变量开头插入一个零