获取 N 天前的日期

Get date for N days before

我发现我的 bat 脚本存在一些问题,该脚本专门用于查找格式为 YYYYMMDD 的日期,但仍然无法找出造成这种行为的原因。

脚本代码:

@ECHO OFF
SetLocal EnableDelayedExpansion
SetLocal

SET CmdFile="C:\cmd.ini"
SET StartDate = ""

call:getDate %1 StartDate

IF EXIST %CmdFile% del %CmdFile%

(
    echo RangeBegin=20%StartDate%
) > %CmdFile%

:getDate
set day=%~1
echo >"%temp%\%~n0.vbs" s=DateAdd("d",%day%,now) : d=weekday(s)
echo>>"%temp%\%~n0.vbs" WScript.Echo year(s)^& right(100+month(s),2)^& right(100+day(s),2)
for /f %%a in ('cscript /nologo "%temp%\%~n0.vbs"') do set "result=%%a"
set "YYYY=%result:~0,4%"
set "MM=%result:~4,2%"
set "DD=%result:~6,2%"
set "data=%YYYY:~2,4%%mm%%dd%"
set "%~2=%data%"
goto:eof

endlocal

因此,我调用了类似 makecmd.bat -10 的脚本,并希望在 C:\ 驱动器中找到一个名为 cmd.ini 的新文件,上下文如下:

RangeBegin=20170627

但是得到了这个:

RangeBegin=20,4~4,2~6,2

我做错了什么?

代码中还有一些错误:

SET StartDate = ""
  • 会将 ""(前导 space)分配给名为 StartDate 的变量 尾随 space
  • 下面的IF EXIST %CmdFile% del %CmdFile%是多余的 尽管如此,echo 还是会覆盖该文件。
  • 由于程序流将到达标签 :getDate,所以应该有一个 goto :eofExit /b 放在前面。
  • vbscript中没有使用变量d,为什么要定义它?
  • vbscript 已经创建了格式为 yyyyMMdd 的日期,为什么 把它分开然后错误地放在剩下的批次部分?
  • 永远无法到达最后一行 endlocal

虽然我怀疑批处理是否应该对驱动器 c 的根目录具有写入权限:这个批处理版本应该这样做:

@ECHO OFF
SetLocal EnableDelayedExpansion

SET CmdFile="C:\cmd.ini"
SET "StartDate="
call:getDate %1 StartDate

 > %CmdFile% echo RangeBegin=%StartDate%

Goto :Eof
:getDate
set day=%~1
echo >"%temp%\%~n0.vbs" s=DateAdd("d",%day%,now) : d=weekday(s)
echo>>"%temp%\%~n0.vbs" WScript.Echo year(s)^& right(100+month(s),2)^& right(100+day(s),2)
for /f %%a in ('cscript /nologo "%temp%\%~n0.vbs"') do set "%~2=%%a"

示例输出:

> SO_44973476.cmd -10
> type cmd.ini
RangeBegin=20170627

如果您不介意批量使用 PowerShell,这将给出完全相同的结果:

@ECHO OFF
for /f %%a in (
  'powershell -NonI -NoP -C "(get-date).AddDays(%~1).ToString(\"yyyyMMdd\")"'
) Do >"C:\cmd.ini" Echo RangeBegin=%%a