31} How many days ago was 31.12.2003? What date was it 100 days ago?
Days since a certain day can be calculated as follows. If the
current day is in the next year (e.g. 2002 vs. 2003) then the method
effectively gives today's annual day number.
@echo off & setlocal enableextensions
::
if defined ProgramW6432 (
echo/
echo Exiting: %~f0 is incompatible with 64-bit Windows
goto :EOF)
::
:: Get and show today's Julian date number
:: Requires DATE2NUM.EXE from tscmd.zip
DATE2NUM /set > "%mytemp%\tmp$$$.cmd"
for %%c in (call del) do %%c "%mytemp%\tmp$$$.cmd"
set dateNumberNow=%datenum_%
echo dateNumberNow=%dateNumberNow%
::
:: Get and show the Julian date number of 31.12.2002
DATE2NUM 31 12 2002 /set > "%mytemp%\tmp$$$.cmd"
for %%c in (call del) do %%c "%mytemp%\tmp$$$.cmd"
set dateNumberThen=%datenum_%
echo dateNumberThen=%dateNumberThen%
::
:: Calculate the difference and show
set /a ago_=%dateNumberNow% - %dateNumberThen%
echo.
echo 31.12.2002 was %ago_% days ago
endlocal & goto :EOF
A screen capture could be something like
D:\TEST>date /t
08.12.2003
D:\TEST>cmdfaq
dateNumberNow=2452982
dateNumberThen=2452640
31.12.2002 was 342 days ago
The problem can also be solved using a Visual Basic Script (VBScript)
aided command line script:
@echo off & setlocal enableextensions
::
set day_=31
set month_=12
set year_=2007
::
>"%temp%\tmp$$$.vbs" echo WScript.Echo DateDiff("d", DateValue("%day_%, %month_%, %year_%"), Date)
for /f %%a in ('cscript //nologo "%temp%\tmp$$$.vbs"') do set ago_=%%a
for %%f in ("%temp%\tmp$$$.vbs") do if exist %%f del %%f
::
date /t
echo %day_%.%month_%.%year_% was %ago_% days ago
endlocal & goto :EOF
A screen capture could be something like
C:\_D\TEST>cmdfaq
03.04.2008
31.12.2007 was 94 days ago
Note how this item opens the door for calculating how old a file is
based on its datetime stamp. This, in turn, can be utilized to solve
the frequent question "
How do I delete from a
folder files which are older than a hundred days?". You might
also wish to take a look at
Item #8.
Next a solution to
the 100 days ago problem:
@echo off & setlocal enableextensions
::
if defined ProgramW6432 (
echo/
echo Exiting: %~f0 is incompatible with 64-bit Windows
goto :EOF)
::
:: Get and show today's Julian date number
:: Requires DATE2NUM.EXE from tscmd.zip
DATE2NUM /set > "%mytemp%\tmp$$$.cmd"
for %%c in (call del) do %%c "%mytemp%\tmp$$$.cmd"
set dateNumberNow=%datenum_%
echo dateNumberNow=%dateNumberNow%
::
:: Subtract a hundred days
set /a dateNumberThen=%dateNumberNow%-100
echo dateNumberThen=%dateNumberThen%
::
:: Convert it back into a date
:: Requires NUM2DATE.EXE from tscmd.zip
NUM2DATE %dateNumberThen% /set > "%mytemp%\tmp$$$.cmd"
for %%c in (call del) do %%c "%mytemp%\tmp$$$.cmd"
echo It was %ddpad_%.%mmpad_%.%yyyy_%
endlocal & goto :EOF
The output would be something like
C:\_D\TEST>date /t
03.04.2008
C:\_D\TEST>cmdfaq
dateNumberNow=2454560
dateNumberThen=2454460
It was 25.12.2007
A Visual Basic Script (VBScript) aided command line script solution
option:
@echo off & setlocal enableextensions
:: Build a Visual Basic Script
set skip=
findstr "'%skip%VBS" "%~f0" > "%temp%\tmp$$$.vbs"
:: Run it with Microsoft Windows Script Host Version 5.6
cscript //nologo "%temp%\tmp$$$.vbs">"%temp%\tmp$$$.cmd"
:: Call the command line script which the script host built
call "%temp%\tmp$$$.cmd"
:: Clean up
for %%f in ("%temp%\tmp$$$.vbs" "%temp%\tmp$$$.cmd") do if exist %%f del %%f
:: Demonstrate the result
echo dtoday_=%dtoday_%
echo ago100_=%ago100_%
echo fut100_=%fut100_%
endlocal & goto :EOF
'
DateNow=Date 'VBS
wscript.echo "@set dtoday_=" & Int(DateNow) 'VBS
wscript.echo "@set ago100_=" & Int(DateNow-100) 'VBS
wscript.echo "@set fut100_=" & Int(DateNow+100) 'VBS
The output might be something like
D:\TEST>cmdfaq
dtoday_=19.02.2005
ago100_=11.11.2004
fut100_=30.05.2005
There are different ways of writing this Visual Basic Script (
VBScript) aided command line script:
@echo off & setlocal enableextensions
>"%temp%\tmp$$$.vbs" echo WScript.Echo Int(Date)
for /f %%a in ('cscript //nologo "%temp%\tmp$$$.vbs"') do set dtoday_=%%a
>"%temp%\tmp$$$.vbs" echo WScript.Echo Int(Date-100)
for /f %%a in ('cscript //nologo "%temp%\tmp$$$.vbs"') do set ago100_=%%a
>"%temp%\tmp$$$.vbs" echo WScript.Echo Int(Date+100)
for /f %%a in ('cscript //nologo "%temp%\tmp$$$.vbs"') do set fut100_=%%a
for %%f in ("%temp%\tmp$$$.vbs") do if exist %%f del %%f
:: Demonstrate the result
echo dtoday_=%dtoday_%
echo ago100_=%ago100_%
echo fut100_=%fut100_%
endlocal & goto :EOF
The output might be something like
Note how this item opens the door for identifying files which have
been made a given number of days ago. Or identifying how old a file
is. The latter task is solved in
FILEAGE.CMD
included in tscmd.zip.
One usage of the results of this item is constructing an XCOPY
parameter. In XCOPY /D:date "Copies files changed on or after the
specified date". E.g. for the previous thirty days you could have
set xcdate_=%mmpad_%
-%ddpad_%
-%yyyy_%
echo xcdate_=%xcdate_%
The needed exact XCOPY date format is dependent on your "
Regional Settings".
@echo off & setlocal enableextensions
::
:: How many days back?
set daysback_=%~1
:: A validity test
echo %daysback_%|findstr "[^1234567890]">nul
if %errorlevel% EQU 0 (
echo.
echo Usage %~f0 DaysBack
goto :EOF)
::
:: Build a Visual Basic Script
set skip=
findstr "'%skip%VBS" "%~f0" > "%temp%\tmp$$$.vbs"
::
:: Run it with Microsoft Windows Script Host Version 5.6
for /f "usebackq tokens=1-3" %%a in (
`cscript //nologo "%temp%\tmp$$$.vbs" "%daysback_%"`) do (
set ddpad_=%%a
set mmpad_=%%b
set yyyy_=%%c)
::
:: Clean up
for %%f in ("%temp%\tmp$$$.vbs") do if exist %%f del %%f
::
:: Demonstrate the result
echo %date%
echo ddpad_=%ddpad_%
echo mmpad_=%mmpad_%
echo yyyy_=%yyyy_%
set xcdate_=%mmpad_%-%ddpad_%-%yyyy_%
echo xcdate_=%xcdate_%
endlocal & goto :EOF
'
DateNow=Date 'VBS
DateThen=CStr(Int(DateNow-WScript.Arguments.Unnamed(0))) 'VBS
Wscript.Echo Mid(DateThen,1,2) + " " + Mid(DateThen,4,2) + " " + Mid(DateThen,7,4) 'VBS
The output might be for example
D:\TEST>D:\TEST\CMDFAQ.CMD 20
22.08.2010
ddpad_=02
mmpad_=08
yyyy_=2010
xcdate_=08-02-2010
A VBS example with yesterday's date
@echo off & setlocal enableextensions
:: Build a Visual Basic Script
set skip=
findstr "'%skip%VBS" "%~f0" > "%temp%\tmp$$$.vbs"
:: Run it with Microsoft Windows Script Host Version 5.6
cscript //nologo "%temp%\tmp$$$.vbs">"%temp%\tmp$$$.cmd"
:: Call the command line script which the script host built
call "%temp%\tmp$$$.cmd"
:: Clean up
for %%f in ("%temp%\tmp$$$.vbs" "%temp%\tmp$$$.cmd") do if exist %%f del %%f
:: Demonstrate the result
echo %date%
echo ddpad_=%ddpad_%
echo mmpad_=%mmpad_%
echo yyyy_=%yyyy_%
endlocal & goto :EOF
'
DateNow=Date 'VBS
Yesterday=CStr(Int(DateNow-1)) 'VBS
wscript.echo "@set ddpad_=" & Mid(Yesterday,1,2) 'VBS
wscript.echo "@set mmpad_=" & Mid(Yesterday,4,2) 'VBS
wscript.echo "@set yyyy_=" & Mid(Yesterday,7,4) 'VBS
The output might be for example
D:\TEST>cmdfaq
19.02.2005
ddpad_=18
mmpad_=02
yyyy_=2005
The problems can also be solved with original script commands only.
To get "How many days ago was 31.12.2002". Local
DD.MM.YYYY date format is assumed.
@echo off & setlocal enableextensions
if "%~3"=="" (
echo Usage: %~0 DD MM YYYY
echo No leading zeros!
goto :EOF)
::
:: Get today's date elements
for /f "tokens=1-3 delims=
./-" %%f in ('date /t') do (
set today_=%%h%%g%%f
set dd_=%%f
set mm_=%%g
set yyyy_=%%h)
:: Omit the leading zeros and trailing spaces
for /f "tokens=* delims=0" %%a in ('echo %dd_%') do set dd_=%%a
for /f "tokens=* delims=0" %%a in ('echo %mm_%') do set mm_=%%a
set yyyy_=%yyyy_:~0,4%
::
:: Get the second date
set day=%~1
set month=%~2
set year=%~3
::
:: Get the Julian day numbers and calculate the difference
call :JDnumber %dd_% %mm_% %yyyy_% jd1_
call :JDnumber %day% %month% %year% jd2_
set /a diff_=%jd1_%-%jd2_%
::
:: Display the result
echo %dd_%.%mm_%.%yyyy_%
echo %day%.%month%.%year%
echo Julian day numbers %jd1_% %jd2_% Difference: %diff_% days
endlocal & goto :EOF
::
:: =========================================================
:: Subroutine: Calculate the chronological Julian Day number
:JDnumber day month year return_
setlocal enableextensions
set /a a=(14-%2)/12
set /a y=%3+4800-%a%
set /a m=%2+12*%a%-3
set /a return_=%1+(153*%m%+2)/5+%y%*365+%y%/4-%y%/100+%y%/400-32045
endlocal & set "%4=%return_%" & goto :EOF
The output might be e.g.
C:\_D\TEST>cmdfaq 31 12 2005
7.9.2006
31.12.2002
Julian day numbers 2453986 2452640 Difference: 1346 days
To get "What date it was 100 days ago?" with original script
commands only:
(Also see
DATEINFO.CMD)
@echo off & setlocal enableextensions
if "%~1"=="" (
echo Usage: %~0 DaysAgo
goto :EOF)
::
:: Get today's date elements
for /f "tokens=1-3 delims=./-" %%f in ('date /t') do (
set today_=%%h%%g%%f
set dd_=%%f
set mm_=%%g
set yyyy_=%%h)
:: Omit the leading zeros and trailing spaces
for /f "tokens=* delims=0" %%a in ('echo %dd_%') do set dd_=%%a
for /f "tokens=* delims=0" %%a in ('echo %mm_%') do set mm_=%%a
set yyyy_=%yyyy_:~0,4%
::
:: How many days back
set daysAgo=%~1
::
:: Get today's Julian day number
call :JDnumber %dd_% %mm_% %yyyy_% dateNumberNow
::
:: Subtract the given number of days
set /a dateNumberThen=%dateNumberNow%-%daysAgo%
::
:: What was the date back then
call :JDinverse %dateNumberThen% day month year
::
:: Display the result
echo dateNumberNow =%dateNumberNow% for %dd_%.%mm_%.%yyyy_%
echo dateNumberThen=%dateNumberThen% for %daysAgo% days ago
echo %day%.%month%.%year%
endlocal & goto :EOF
::
:: =========================================================
:: Subroutine: Calculate the chronological Julian Day number
:JDnumber day month year return_
setlocal enableextensions
set /a a=(14-%2)/12
set /a y=%3+4800-%a%
set /a m=%2+12*%a%-3
set /a return_=%1+(153*%m%+2)/5+%y%*365+%y%/4-%y%/100+%y%/400-32045
endlocal & set "%4=%return_%" & goto :EOF
::
:: ===============================================
:: Subroutine: Get the date of a Julian Day number
:JDinverse dateNumber day month year
setlocal enableextensions
set /a a=%1+32044
set /a b=(4*%a%+3)/146097
set /a c=%a%-(%b%*146097)/4
set /a d=(4*%c%+3)/1461
set /a e=%c%-(1461*%d%)/4
set /a m=(5*%e%+2)/153
set /a day=%e%-(153*%m%+2)/5+1
set /a month=%m%+3-12*(%m%/10)
set /a year=%b%*100+%d%-4800+%m%/10
endlocal &set "%2=%day%" &set "%3=%month%" &set "%4=%year%" &goto :EOF
The output might be e.g.
C:\_D\TEST>cmdfaq 100
dateNumberNow =2453986 for 7.9.2006
dateNumberThen=2453886 for 100 days ago
30.5.2006
A
GnuAWK solution to the "What date it
was 100 days ago?" problem:
@echo off & setlocal enableextensions
set gawk_=C:\_F\FTOOLS\unxgawk.exe
if not exist "%gawk_%" (
echo The "%gawk_%" program needed for this script not found
goto :EOF)
::
if "%~1"=="" (
echo Usage: %~0 DaysAgo
goto :EOF)
::
set daysAgo=%~1
for /f "tokens=* delims=" %%a in ('
%gawk_% "BEGIN{printf\"%%s\n\",strftime(\"%%d.%%m.%%Y\",systime())}"') do (
set dateNow=%%a)
for /f "tokens=* delims=" %%a in ('
%gawk_% "BEGIN{printf\"%%s\n\",strftime(\"%%d.%%m.%%Y\",systime()-%daysAgo%*86400)}"') do (
set dateThen=%%a)
::
echo dateNow %dateNow%
echo dateThen %dateThen%
endlocal & goto :EOF
The output might be e.g.
C:\_D\TEST>cmdfaq 100
dateNow 12.03.2011
dateThen 02.12.2010
Let's return to the "How many days ago was 31.12.2003?" problem with
a
GnuAWK solution:
@echo off & setlocal enableextensions
set gawk_=C:\_F\FTOOLS\unxgawk.exe
if not exist "%gawk_%" (
echo The "%gawk_%" program needed for this script not found
goto :EOF)
if "%~3"=="" (
echo Usage: %~0 YYYY MM DD
goto :EOF)
::
for /f "tokens=* delims=" %%a in ('
%gawk_% "BEGIN{printf\"%%s\n\",strftime(systime())}"') do (
set syssecNow=%%a)
for /f "tokens=* delims=" %%a in ('
%gawk_% "BEGIN{printf\"%%s\n\",mktime(\"%~1 %~2 %~3 00 00 00\")}"') do (
set syssecThen=%%a)
::
set /a daysSince=(%syssecNow%-%syssecThen%)/86400
echo %~3.%~2.%~1 was %daysSince% days ago
endlocal & goto :EOF
The output might be e.g.
C:\_D\TEST>cmdfaq 2003 12 31
31.12.2003 was 2628 days ago