<http://www.netikka.net/tsneti/info/tscmd031.htm>
Copyright © 2003- by Prof. Timo Salmi  
Last modified Fri 2-Jan-2015 01:06:45

 
Assorted NT/2000/XP/.. CMD.EXE Script Tricks
From the html version of the tscmd.zip 1cmdfaq.txt file
To the Description and the Index
 

This page is edited from the 1cmdfaq.txt faq-file contained in my tscmd.zip command line interface (CLI) collection. That zipped file has much additional material, including a number of detached .cmd script files. It is recommended that you also get the zipped version as a companion.

Please see "The Description and the Index page" for the conditions of usage and other such information.



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

References/Comments: (If a Google message link fails try the links within the brackets.)
  Google Groups Feb 12 2005, 6:58 pm [M]
  Google Groups Nov 9 2005, 4:34 pm [M]
  Is there a formula for calculating the Julian day number
  Using gawk's Timestamp Functions