13

I know how to get today's date in Windows 7. here is the command that I am using:

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

But I want to get yesterday, I do not know how.

user1188125
  • 677
  • 2
  • 13
  • 21
  • http://www.robvanderwoude.com/datetimentmath.php – craig65535 Aug 09 '12 at 20:27
  • 1st link when googling date subtraction batch file: http://stackoverflow.com/questions/355425/date-arithmetic-in-dos-scripting – Andrew Aug 09 '12 at 21:04
  • 5
    since it's w7, why not use tools available: `powershell get-date((get-date).addDays(-1)) -uformat "%Y%m%d"` – wmz Aug 09 '12 at 21:14
  • @wmz as for me (win 8.1) better use `powershell get-date((get-date).addDays(-1)) -uformat '%Y-%m-%d'` - date format parameters in single quote. – Mykola Vasilaki Sep 09 '16 at 10:18
  • Possible duplicate of [How to get 3 days past date from current date Using Batch file](https://stackoverflow.com/questions/22191084/how-to-get-3-days-past-date-from-current-date-using-batch-file) – phuclv Feb 27 '18 at 15:09

4 Answers4

17

If you're limited to just cmd.exe, then the other solutions, despite their size, are probably as good as you'll get. However, modern Windows (such as your Win7) ships with quite a few other tools which can do the job far easier.

Just create a VBScript yester.vbs script as follows:

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

Then you can call it from your cmd script with:

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

and the yesterday variable will be created in the form yyyymmdd for you to manipulate however you desire.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • **Comment 1:** Make sure that C:\Windows\System32 is in your PATH, otherwise it will throw an error: `'cscript' is not recognized as an internal or external command.` This can be solved by replacing `cscript` by `"%SystemRoot%\System32\cscript.exe"` in the `for.....`. See this https://stackoverflow.com/questions/13976872/cscript-is-not-recognized-inside-a-batch – JejeBelfort Jan 30 '19 at 06:14
  • 2
    **Comment 2:** If you want to execute `for /f %%a in ('cscript //nologo yester.vbs') do set yesterday=%%a` directly in the `cmd` terminal, you should replace the `%%` by `%`, otherwise you will get the following error message: `%%A was unexpected at this time`. See this https://stackoverflow.com/questions/9311562/a-was-unexpected-at-this-time – JejeBelfort Jan 30 '19 at 06:16
  • Jeje, I believe system32 is in the path by default. If someone has removed it, it's on them to fix the issue - I assume someone actively removing it will know the consequences. On the double-percent comment, you raise a good point but the question explicitly stated 'in a batch file'. – paxdiablo Jan 30 '19 at 08:20
  • 1
    Yes sure, sorry the comments are not really aiming at your answer (which I +1 btw) but are here to help people who encountered problems like me while implementing it ;) – JejeBelfort Jan 30 '19 at 08:30
9

Found a script that will work to ensure you get the previous day even if the year or month changes 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%
09stephenb
  • 9,358
  • 15
  • 53
  • 91
Greg
  • 141
  • 5
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
amigo
  • 155
  • 1
  • 10
2

Here's a solution that creates the earlierday.vbs file on the fly, uses it and deletes it afterwards.

It stores the result in the NewDate variable

This example calculates 1 day ago, but can easily calculate a date further back by changing the value of the Offset variable.

@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

You could refine this slightly by using %temp%\earlierday.vbs to create the file in the user's temp folder.

Credits to paxdiablo as this is a simple tweak on his earlier post.

EDIT: Here's something with a loop, close to what I actually need it to do. This will take 14 days off today's date and return that date. Then it will keep going back 7 days at a time until it gets to 35 days day ago.

@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
Alex Wilson
  • 91
  • 1
  • 4