如何在批处理文件中获取昨天的日期

13

我知道如何在Windows 7中获取今天的日期。以下是我正在使用的命令:

%DATE:~6,4%%DATE:~3,2%%DATE:~0,2%

但我想获取昨天的日期,不知道该怎么做。


http://www.robvanderwoude.com/datetimentmath.php - craig65535
在谷歌搜索日期减法批处理时,第一个链接是:https://dev59.com/TnRC5IYBdhLWcg3wROzk。请注意,只需翻译文本内容,不要进行解释。 - Andrew
5
既然是W7系统,为什么不使用现有的工具呢?翻译后的命令为:powershell get-date((get-date).addDays(-1)) -uformat "%Y%m%d",意思是获取前一天的日期并以“年月日”的格式输出。 - wmz
@wmz 对于我来说(win 8.1),最好使用 powershell get-date((get-date).addDays(-1)) -uformat '%Y-%m-%d' - 在单引号中使用日期格式参数。 - Mykola Vasilaki
4个回答

17

如果你只能使用仅有的cmd.exe,那么尽管其他解决方案大小不同,但它们可能是你能得到的最好的。然而,现代Windows(例如Win7)随附了许多其他工具,这些工具可以更轻松地完成任务。

只需按照以下步骤创建一个VBScript yester.vbs脚本:

d = date() - 1
wscript.echo year(d) * 10000 + month(d) * 100 + day(d)

然后您可以使用以下命令从cmd脚本调用它:

for /f %%a in ('cscript //nologo yester.vbs') do set yesterday=%%a

同时,yesterday变量将以yyyymmdd的形式创建,供您随意操作。


注释1:确保C:\ Windows \ System32在您的PATH中,否则它会抛出错误:“'cscript'不被识别为内部或外部命令。”这可以通过在“for .....”中将cscript替换为“%SystemRoot%\ System32 \ cscript.exe”来解决。请参见https://dev59.com/32zXa4cB1Zd3GeqPSVfu - JejeBelfort
2
注释2:如果您想直接在“cmd”终端中执行for /f %%a in ('cscript //nologo yester.vbs') do set yesterday=%%a,则应将“%%”替换为“%”,否则您将收到以下错误消息:“%%A was unexpected at this time”。请参见此链接:https://dev59.com/k2ox5IYBdhLWcg3wSCVW - JejeBelfort
我相信system32默认在路径中。如果有人删除了它,那么解决这个问题就是他们的责任——我认为主动删除它的人会知道后果。关于双百分号注释,你提出了一个好点,但问题明确表示“在一个批处理文件中”。 - paxdiablo
1
是的,当然可以。抱歉,这些评论并不是针对你的答案(我顺便点了个赞),而是为了帮助像我一样在实现时遇到问题的人们。;) - JejeBelfort

9
发现一种脚本,即使年份或月份改变也能确保您获得前一天的日期,具体请参考Dos Yesterday Batch
@echo off

set yyyy=

set $tok=1-3
for /f "tokens=1 delims=.:/-, " %%u in ('date /t') do set $d1=%%u
if "%$d1:~0,1%" GTR "9" set $tok=2-4
for /f "tokens=%$tok% delims=.:/-, " %%u in ('date /t') do (
for /f "skip=1 tokens=2-4 delims=/-,()." %%x in ('echo.^|date') do (
set %%x=%%u
set %%y=%%v
set %%z=%%w
set $d1=
set $tok=))

if "%yyyy%"=="" set yyyy=%yy%
if /I %yyyy% LSS 100 set /A yyyy=2000 + 1%yyyy% - 100

set CurDate=%mm%/%dd%/%yyyy%
set dayCnt=%1

if "%dayCnt%"=="" set dayCnt=1

REM Substract your days here
set /A dd=1%dd% - 100 - %dayCnt%
set /A mm=1%mm% - 100

:CHKDAY
if /I %dd% GTR 0 goto DONE
set /A mm=%mm% - 1
if /I %mm% GTR 0 goto ADJUSTDAY
set /A mm=12
set /A yyyy=%yyyy% - 1

:ADJUSTDAY
if %mm%==1 goto SET31
if %mm%==2 goto LEAPCHK
if %mm%==3 goto SET31
if %mm%==4 goto SET30
if %mm%==5 goto SET31
if %mm%==6 goto SET30
if %mm%==7 goto SET31
if %mm%==8 goto SET31
if %mm%==9 goto SET30
if %mm%==10 goto SET31
if %mm%==11 goto SET30
REM ** Month 12 falls through

:SET31
set /A dd=31 + %dd%
goto CHKDAY

:SET30
set /A dd=30 + %dd%
goto CHKDAY

:LEAPCHK
set /A tt=%yyyy% %% 4
if not %tt%==0 goto SET28
set /A tt=%yyyy% %% 100
if not %tt%==0 goto SET29
set /A tt=%yyyy% %% 400
if %tt%==0 goto SET29

:SET28
set /A dd=28 + %dd%
goto CHKDAY

:SET29
set /A dd=29 + %dd%
goto CHKDAY

:DONE
if /I %mm% LSS 10 set mm=0%mm%
if /I %dd% LSS 10 set dd=0%dd%

REM Set IIS and AWS date variables
set IISDT=%yyyy:~2,2%%mm%%dd%
set AWSDT=%yyyy%-%mm%-%dd%

4
@echo off
:: Strip the day of the week from the current date
FOR %%A IN (%Date%) DO SET Today=%%A
:: Parse the date, prefix day and month with an extra leading zero
FOR /F "tokens=1-3 delims=/" %%A IN ("%Today%") DO (
    SET Day=0%%A
    SET Month=0%%B
    SET Year=%%C
)
:: Remove excess leading zeroes
SET Day=%Day:~-2%
SET Month=%Month:~-2%
:: Display the results
SET Day
SET Month
SET Year
:: Convert to Julian date
CALL :JDate %Year% %Month% %Day%
:: Display the result
SET JDate
:: Subtract 1 day
SET /A JPast = JDate - 1
:: Display the result
SET JPast
:: Convert back to "normal" date again
CALL :GDate %JPast%
:: Display the result
::SET GDate=20130121
SET GDate

echo The previous day in form YYYYMMDD is %GDate%

pause
::::::::::::::::::::::::::::::::::::::::::::::::::::::

GOTO:EOF

:JDate
:: Convert date to Julian
:: Arguments : YYYY MM DD
:: Returns   : Julian date
::
:: First strip leading zeroes
SET MM=%2
SET DD=%3
IF %MM:~0,1% EQU 0 SET MM=%MM:~1%
IF %DD:~0,1% EQU 0 SET DD=%DD:~1%
::
:: Algorithm based on Fliegel-Van Flandern
:: algorithm from the Astronomical Almanac,
:: provided by Doctor Fenton on the Math Forum
:: (http://mathforum.org/library/drmath/view/51907.html),
:: and converted to batch code by Ron Bakowski.
SET /A Month1 = ( %MM% - 14 ) / 12
SET /A Year1  = %1 + 4800
SET /A JDate  = 1461 * ( %Year1% + %Month1% ) / 4 + 367 * ( %MM% - 2 -12 * %      Month1% ) / 12 - ( 3 * ( ( %Year1% + %Month1% + 100 ) / 100 ) ) / 4 + %DD% - 32075

SET Month1=
SET Year1=
GOTO:EOF
:GDate
:: Convert Julian date back to "normal" Gregorian date
:: Argument : Julian date  
:: Returns  : YYYY MM DD
:: 
:: Algorithm based on Fliegel-Van Flandern
:: algorithm from the Astronomical Almanac,
:: provided by Doctor Fenton on the Math Forum
:: (http://mathforum.org/library/drmath/view/51907.html),
:: and converted to batch code by Ron Bakowski.
::
SET /A P      = %1 + 68569
SET /A Q      = 4 * %P% / 146097
SET /A R      = %P% - ( 146097 * %Q% +3 ) / 4
SET /A S      = 4000 * ( %R% + 1 ) / 1461001
SET /A T      = %R% - 1461 * %S% / 4 + 31
SET /A U      = 80 * %T% / 2447
SET /A V      = %U% / 11
SET /A GYear  = 100 * ( %Q% - 49 ) + %S% + %V%
SET /A GMonth = %U% + 2 - 12 * %V%
SET /A GDay   = %T% - 2447 * %U% / 80
:: Clean up the mess
FOR %%A IN (P Q R S T U V) DO SET %%A=
:: Add leading zeroes
IF 1%GMonth% LSS 20 SET GMonth=0%GMonth%
IF 1%GDay%   LSS 20 SET GDay=0%GDay%
:: Return value
:: Here you can define the form that you want
SET GDate=%GYear%%GMonth%%GDay%
GOTO:EOF

2
这里有一个解决方案,它可以动态创建earlierday.vbs文件并使用它,最后将其删除。它将结果存储在NewDate变量中。该示例计算1天前的日期,但是通过更改Offset变量的值,可以轻松地计算更早的日期。
@echo off
set Offset=1

echo d = date() - WScript.Arguments.Item(0) > earlierday.vbs
echo wscript.echo year(d) * 10000 + month(d) * 100 + day(d) >> earlierday.vbs

for /f %%a in ('cscript //nologo earlierday.vbs %Offset%') do set NewDate=%%a

del earlierday.vbs    
echo %NewDate%
pause

您可以通过使用%temp%\earlierday.vbs 在用户的临时文件夹中创建文件,以稍微改进此功能。
感谢paxdiablo,因为这是对他早期帖子的简单修改。
编辑:这里有一个循环,接近我实际需要做的事情。它将从今天的日期减去14天并返回该日期。然后,它将每次倒退7天,直到回到35天前。
@echo off
SETLOCAL EnableDelayedExpansion

set BackDaysFrom=14
Set BackDaysTo=35
Set BackDaysStep=7

echo d = date() - WScript.Arguments.Item(0) > earlierday.vbs
echo wscript.echo year(d) * 10000 + month(d) * 100 + day(d) >> earlierday.vbs

for /L %%i in (%BackDaysFrom%, %BackDaysStep%, %BackDaysTo%) do (
    for /f %%a in ('cscript //nologo earlierday.vbs %%i') do set NewDate=%%a
    echo !NewDate!
)

del earlierday.vbs    

pause

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接