<http://www.netikka.net/tsneti/info/tscmd070.htm>
Copyright © 2003-2011 by Prof. Timo Salmi  
Last modified Tue 29-Nov-2011 19:16:08

 
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.



70} Calendar: What weekday was December 31, 2004?

A Visual Basic Script (VBScript) aided command line script solution:
  @echo off & setlocal enableextensions
  if not exist c:\mytemp mkdir c:\mytemp
  echo>c:\mytemp\tmp$$$.vbs WScript.Echo WeekDayName(Weekday(DateValue("December 31, 2004")),true)
  for /f %%d in ('cscript //nologo c:\mytemp\tmp$$$.vbs') do set wd_=%%d
  for %%f in (c:\mytemp\tmp$$$.vbs) do if exist %%f del %%f
  rmdir c:\mytemp
  echo Weekday on December 31, 2004 is wd_=%wd_%
  endlocal & goto :EOF

The output will be
  D:\TEST>cmdfaq
  Weekday on December 31, 2004 is wd_=Fri

Likewise:
  @echo off & setlocal enableextensions
  if not exist c:\mytemp mkdir c:\mytemp
  echo>c:\mytemp\tmp$$$.vbs WScript.Echo DatePart("y",DateValue("December 31, 2004"))
  for /f %%d in ('cscript //nologo c:\mytemp\tmp$$$.vbs') do set dn_=%%d
  for %%f in (c:\mytemp\tmp$$$.vbs) do if exist %%f del %%f
  rmdir c:\mytemp
  echo The ordinal number day of year on December 31, 2004 is dn_=%dn_%
  endlocal & goto :EOF

The output will be
  D:\TEST>cmdfaq
  The ordinal number day of year on December 31, 2004 is dn_=366

Further information:
  @echo off & setlocal enableextensions
  if not exist c:\mytemp mkdir c:\mytemp
  echo>c:\mytemp\tmp$$$.vbs WScript.Echo DatePart("ww",DateValue("December 31, 2004"),vbMonday,vbFirstFourDays)
  for /f %%w in ('cscript //nologo c:\mytemp\tmp$$$.vbs') do set wn_=%%w
  for %%f in (c:\mytemp\tmp$$$.vbs) do if exist %%f del %%f
  rmdir c:\mytemp
  echo The week number on December 31, 2004 is wn_=%wn_%
  endlocal & goto :EOF

The output will be
  D:\TEST>cmdfaq
  The week number on December 31, 2004 is wn_=53

Words of caution about the week number from Dr. John Stockton are in order. "One cannot trust software of US origin to attempt the ISO week number, nor to get it right when they do. An ISO 8601 week number routine needs to return both week and year; both 2004-12-27 and 2005-01-02 will be in Week 2004-53; Week 2004-01 was 2003-12-29 to 2004-01-04. ... Most Americans, AIUI, will want some other definition entirely. ... The potential users should do a comprehensive test on their own systems to ensure that the results given are always correct according to the week number system that their bosses expect/need. One should really test Weeks 1, 52 [53] for all 14 possible year types (leap/non-Leap, starting Mon-Sun)."

An ISO 8601 week number example based on the WeekNumJRS subroutine provided by John:
  @echo off & setlocal enableextensions
  ::
  :: Set an example date for this demonstration

  set day_=28
  set month_=03
  set year_=2008
  ::
  :: Build a Visual Basic Script

  set temp_=%temp%
  if defined mytemp if exist "%mytemp%\" set temp_=%mytemp%
  set skip=
  findstr "'%skip%VBS" "%~f0" > "%temp_%\tmp$$$.vbs"
  ::
  :: Run the VBS script with Microsoft Windows Script Host Version 5.6

  cscript //nologo "%temp_%\tmp$$$.vbs" %year_% %month_% %day_%
  ::
  :: Clean up

  for %%f in ("%temp_%\tmp$$$.vbs") do if exist "%%~f" del "%%~f"
  endlocal & goto :EOF
  '
  '................................................................
  'The Visual Basic Script
  '

  Sub WeekNumJRS(Tdy, YNo, WNo, DoW) '' Tdy is Date in; Y W D out 'VBS
    Dim N, Thu, SoY '' ISO 8601 Y>=1900 ( because of \ ) 'VBS
    N = 2 'VBS
    Thu = ((Tdy+3+N) \ 7) * 7 - N '' Nearest Thu 'VBS
    YNo = Year(Thu) 'VBS
    SoY = DateSerial(YNo, 1, 1) '' Date, YYYY-01-01 'VBS
    WNo = ((Thu - SoY) \ 7) + 1 'VBS
    DoW = ((Tdy+5) mod 7) + 1 'VBS
  End Sub 'VBS
  '
  Sub MainProgram() 'VBS
    set x = WScript.Arguments 'VBS
    MyDate = DateSerial(x(0), x(1), x(2)) 'VBS
    WeekNumJRS MyDate, Yno, Wno, DoW 'VBS
    WScript.Echo "MyDate", MyDate 'VBS
    WScript.Echo "Yno", Yno 'VBS
    WScript.Echo "Wno", Wno 'VBS
    WScript.Echo "DoW", DoW 'VBS
  End Sub 'MainProgram 'VBS
  '
  MainProgram 'VBS

The output will be
  D:\TEST>cmdfaq
  MyDate 28.03.2008
  Yno 2008
  Wno 13
  DoW 5

Next, consider the question "how many days are there in a month?"
  @echo off & setlocal enableextensions
  :: Build a Visual Basic Script
  if not exist c:\mytemp mkdir c:\mytemp
  findstr "'%skip%VBS" "%~f0" > c:\mytemp\tmp$$$.vbs
  ::
  :: Assume a local date format dd.mm.yyyy
  :: Customize, if necessary

  set month_=2
  set year_=2004
  ::
  :: Run the VBS script with Microsoft Windows Script Host Version 5.6

  cscript //nologo c:\mytemp\tmp$$$.vbs
  call c:\mytemp\tmp$$$.cmd
  echo %mmdays_% days in %month_%.%year_%
  ::
  :: Clean up

  for %%f in (c:\mytemp\tmp$$$.vbs c:\mytemp\tmp$$$.cmd) do del %%f
  rmdir c:\mytemp
  endlocal & goto :EOF
  '
  '................................................................
  'The Visual Basic Script
  '

  Const ForReading = 1, ForWriting = 2, ForAppending = 8 'VBS
  Dim MyDate, mm, yyyy, DaysInMonth, fout, FSO 'VBS
  '
  Set WshShell = WScript.CreateObject("WScript.shell") 'VBS
  mm=WshShell.ExpandEnvironmentStrings("%month_%") 'VBS
  yyyy=WshShell.ExpandEnvironmentStrings("%year_%") 'VBS
  '
  For i = 28 to 32 'VBS
    Mydate = MonthName(mm, False) & " " & CStr(i) & ", " & CStr(yyyy) 'VBS
    If (IsDate(MyDate)) Then 'VBS
      DaysInMonth = i 'VBS
    End If 'VBS
  Next 'VBS
  '
  Set FSO = CreateObject("Scripting.FileSystemObject") 'VBS
  Set fout = FSO.OpenTextFile("c:\mytemp\tmp$$$.cmd", ForWriting, true) 'VBS
  fout.WriteLine "@set mmdays_=" & DaysInMonth 'VBS
  fout.Close 'VBS

The output will be
  D:\TEST>cmdfaq
  29 days in 2.2004

A comment from Dr John Stockton in Google Groups May 28 2006, 4:46 pm [M]
  DaysInMonth = Day(DateSerial(yyyy, mm+1, 0)) ' VBS
"seems simpler". My comment. Yes, indeed. And this goes to show how much a task can be condensed if written suitably in another way:
  @echo off & setlocal enableextensions
  ::
  :: Test with these

  set month_=2
  set year_=2004
  ::
  :: Get it

  echo>"%temp%\tmp$$$.vbs" WScript.Echo Day(DateSerial(%year_%, %month_%+1, 0))
  for /f %%d in ('cscript //nologo "%temp%\tmp$$$.vbs"') do set mmdays_=%%d
  if exist "%temp%\tmp$$$.vbs" del "%temp%\tmp$$$.vbs"
  ::
  :: Display the result

  echo %mmdays_% days in %month_%.%year_%
  endlocal & goto :EOF

Let's get back to the original problem of getting the weekday. The problem can also be solved with pure script commands as follows: (Also see DATEINFO.CMD)
  @echo off & setlocal enableextensions disabledelayedexpansion
  if "%~3"=="" (
    echo Usage: %~0 DD MM YYYY
    echo No leading zeros!
    goto :EOF)
  ::
  set dd_=%~1
  set mm_=%~2
  set yyyy_=%~3
  ::
  set /a a_=(14-%mm_%)/12
  set /a y_=%yyyy_%-%a_%
  set /a m_=%mm_%+12*%a_%-2
  set /a wdnum_=1+(%dd_%+%y_%+%y_%/4-%y_%/100+%y_%/400+(31*%m_%)/12)%%7
  ::
  echo %dd_% %mm_% %yyyy_%
  for /f "tokens=%wdnum_%" %%d in (
    'echo Sun Mon Tue Wed Thu Fri Sat') do set wd_=%%d
  echo %wd_%
  endlocal & goto :EOF

The output could be e.g.
  C:\_D\TEST>cmdfaq 31 12 2004
  31 12 2004
  Fri

References/Comments: (If a Google message link fails try the links within the brackets.)
  About the calendar issues in this FAQ
  A page about the Christian Calendar
  Google Groups Feb 18 2007, 11:58 am [M]
  VBScript Date and Time Index, J R Stockton