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