Calendar Script

391 views
Skip to first unread message

Frank

unread,
Sep 27, 2001, 10:57:19 AM9/27/01
to
Here's a small calendar script that prints the current month. Long lines
have been wrapped with the escape character '^' and can be left as is. This
script relies on the output format of DATE/T that is used on my computer,
which I suspect is the same for most computers, so it may not work on some
systems.

Some of the lines in this script use uncommon (if not new) techniques that
may be worth studying. One example that comes to mind is the use of SET/A
to get the first number of, for example, "31:1" in %MonthDays%.

Frank

::BEGIN SCRIPT::::::::::::::::::::::::::::::::::::::::::::
@Echo OFF
SetLocal ENABLEEXTENSIONS
REM Calendar of current month
REM Written by Frank P. Westlake, 2001.09.25

Goto :BeginScript
:Build
Set num=%1
If DEFINED blanks (
Set Line=%blanks%
Set Blanks=
)
If %num% LSS 10 (Set Line=%Line% %num%) ^
Else (Set Line=%Line%%num%)
If %num% EQU %domz% Goto :Print
Set /A "test=dom1%%7,dom1+=1"
If %test% LSS 6 Set Line=%Line% &Goto :EOF
:Print
Echo.%Line%
Set Line=
Goto :EOF
:BeginScript
Set WeekDays=0:Sun,1:Mon,2:Tue,3:Wed,4:Thu,5:Fri,6:Sat
Set MonthDays=31:1,28:2,31:3,30:4,31:5,30:6,31:7^
31:8,30:9,31:10,30:11,31:12
Set Months=January February March April May June July August September^
October November December
For /F "tokens=1-4 delims=/ " %%a in ('DATE/T') Do (
Set dow=%%a
Set Month=%%b
Set Day=%%c
Set Year=%%d
)
If %Month:~0,1%==0 Set Month=%Month:~1%
For /F "tokens=%Month%" %%a in ('Echo %Months%') Do Set MonthName=%%a
For %%a in (%Weekdays%) Do Echo.%%a|Find "%dow%">NUL:&&Set dow#=%%a
For %%a in (%Monthdays%) Do Echo.%%a|FindStr/el ":%Month%">NUL:&&Set^
domz=%%a
Set /A domz=domz
If %Month% NEQ 2 Goto :NoLeap
Set /A "Leap1=year%%4,Leap2=year%%100,Leap3=year%%400"
If %Leap1% EQU 0 (Set Leap1=1) Else (Set Leap1=0)
If %Leap2% EQU 0 (Set Leap2=0) Else (Set Leap2=1)
If %Leap3% EQU 0 (Set Leap3=1) Else (Set Leap3=0)
Set /A "Leap=%Leap1% & %Leap2% | %Leap3%"
Set /A domz+=Leap
:NoLeap
Set dow#=%dow#:~0,1%
Set /A "dom1=Day-dow#,dom1%%=7,dom1=8-dom1,dom1%%=7"
Set /A i=dom1
:loop1
If %i% GTR 0 Set /A i-=1&Set blanks=%blanks% &Goto :loop1
Echo.%MonthName% %Year%
Echo.Sun Mon Tue Wed Thu Fri Sat
For /L %%a in (1,1,%domz%) Do Call :Build %%a
::END SCRIPT::::::::::::::::::::::::::::::::::::::::::::::

Phil Robyn

unread,
Sep 28, 2001, 2:40:34 AM9/28/01
to
Frank wrote:

Hi, Frank,

I LIKE this! If you send me your e-mail address, I'll send you some calendar
batch files (big month, small month, quarter, year). I don't feel like posting them
to the newsgroup 'cause they're too lengthy.

I like your calculating whether the year is a leap year. I took a different approach
of just looking up the year in a list of leap years (since the list of leap years never
changes)

:DaysInMonth

set nmm=%zmm%X
if %nmm:~1,1%==X (
set nmm=0%zmm%
) else (
set nmm=%zmm%
)
set /a tstmm = 1%nmm% - 100
for /f "tokens=%tstmm%" %%a in (
'echo 31 28 31 30 31 30 31 31 30 31 30 31'
) do set days_in_month=%%a

if "%nmm%" NEQ "02" goto :EOF

for %%a in (
1980 1984 1988 1992 1996 2000 2004 2008 2012 2016 2020 2024
2028 2032 2036 2040 2044 2048 2052 2056 2060 2064 2068 2072
2076
) do if %%a==%zyy% set /a days_in_month+=1
goto :EOF

Also, the earliest possible date seems to be limited by NT to 01/01/1980; I
don't think it's possible to set the system date to an earlier value.

Regards,
Phil Robyn
Univ. of California, Berkeley


--

u n z i p m y a d d r e s s t o s e n d e - m a i l


Frank

unread,
Sep 28, 2001, 6:16:45 AM9/28/01
to
Phil Robyn <3BB41B5B...@uclink.berkzipeley.edu>...

^ I like your calculating whether the year is a leap year. I took
^ a different approach of just looking up the year in a list of leap
^ years (since the list of leap years never changes)

It's certainly faster that way. I guess I still feel the need to somehow
justify all those math classes I took.

Frank

Al Dunbar

unread,
Sep 29, 2001, 1:32:42 PM9/29/01
to

"Frank" <vfocd...@avhjmgkajwgpujub.com> wrote in message
news:01c14806$a75ae480$0125250a@avhjmgkajwgpujub...

> Phil Robyn <3BB41B5B...@uclink.berkzipeley.edu>...
>
> ^ I like your calculating whether the year is a leap year. I took
> ^ a different approach of just looking up the year in a list of leap
> ^ years (since the list of leap years never changes)

Agreed, but then the list of all leap years is infinite in length, is it not
grasshopper?

> It's certainly faster that way. I guess I still feel the need to somehow
> justify all those math classes I took.

Hmmm... I don't think your math professors/teachers would like the idea of
you using such an inefficient and mathematically simple thing as the batch
language as a way to keep your math skills sharp :-)

/Al

Phil Robyn

unread,
Sep 29, 2001, 8:54:19 PM9/29/01
to
Al Dunbar wrote:

> "Frank" <vfocd...@avhjmgkajwgpujub.com> wrote in message
> news:01c14806$a75ae480$0125250a@avhjmgkajwgpujub...
> > Phil Robyn <3BB41B5B...@uclink.berkzipeley.edu>...
> >
> > ^ I like your calculating whether the year is a leap year. I took
> > ^ a different approach of just looking up the year in a list of leap
> > ^ years (since the list of leap years never changes)
>
> Agreed, but then the list of all leap years is infinite in length, is it not
> grasshopper?

The list may be infinite, but I will not be around after 2076, and I'm
sure I won't be executing my batch file that lazily looks up the leap
years in a table rather than calculating them for too many more years ...

>
> > It's certainly faster that way. I guess I still feel the need to somehow
> > justify all those math classes I took.
>
> Hmmm... I don't think your math professors/teachers would like the idea of
> you using such an inefficient and mathematically simple thing as the batch
> language as a way to keep your math skills sharp :-)
>
> /Al

I find date calculations abysmally slow in batch, so for serious date calculations
I built a date table from 01/01/1980 to 12/31/2079 and just do very rapid
table lookups instead of actually calculating dates. I find that this date range
is perfectly adequate for my needs.

Frank

unread,
Sep 29, 2001, 10:08:53 PM9/29/01
to
Phil Robyn <3BB66D35...@uclink.berkzipeley.edu>...

^ I find date calculations abysmally slow in batch, so for serious
^ date calculations I built a date table...

Doing table lookups instead of lengthy calculations is also common in
programming mathematics functions for science and engineering.

Frank

Frank

unread,
Oct 29, 2001, 10:52:09 AM10/29/01
to
Frank <01c14764$b0bf6700$0b432640@erafrbqcjahdbcys>...

^ Here's a small calendar script that prints the current month.

Here's a not-as-small calendar script that will print any Gregorian month
or year.

Frank

::BEGINNING OF SCRIPT:::::::::::::::::::::::::::::::::::::::::::::::::::
::Calendar.cmd
:!:Prints Gregorian Calendar (1582.10.15++) for the current month or the
:!:specified month or year.
:!:Written by Frank P. Westlake, 2001.09.25, 2001.10.29
:!:
:!:Usage: Calendar [Year[-Month]]
:!:
:!: Year The desired year, including century.
:!: Month The desired month.
:!: - A space or any of .,;/-=
:!:
:!:With no arguments, only the current month is printed. The current day
:!:is marked with an asterisk (*).
:!:
:!:Examples:
:!: Calendar
:!: Calendar 2001
:!: Calendar 2001.10
:!:
@Echo OFF&SetLocal ENABLEEXTENSIONS
Set arg1=%1&Call :Help||Goto :EOF


Goto :BeginScript
:Build
Set num=%1

If DEFINED blanks (Set Line=%blanks%&Set Blanks=)
If %num% LSS 10 Set num= %num%
Set Line=%Line%%num%
If %Hoy% EQU 1 If %num% EQU %Day% Call Set Line=%%Line:^%num% =^%num%*%%


If %num% EQU %domz% Goto :Print
Set /A "test=dom1%%7,dom1+=1"
If %test% LSS 6 Set Line=%Line% &Goto :EOF
:Print
Echo.%Line%

Set Line=&Goto :EOF


:BeginScript
Set WeekDays=0:Sun,1:Mon,2:Tue,3:Wed,4:Thu,5:Fri,6:Sat
Set MonthDays=31:1,28:2,31:3,30:4,31:5,30:6,31:7^
31:8,30:9,31:10,30:11,31:12
Set Months=January February March April May June July August September^

October November December &Set Repeat=:EOF


For /F "tokens=1-4 delims=/ " %%a in ('DATE/T') Do (

Set dow=%%a&Set Month=%%b&Set Day=%%c&Set Year=%%d&Set ym=%%d.%%b)


For %%a in (%Weekdays%) Do Echo.%%a|Find "%dow%">NUL:&&Set dow#=%%a

If NOT "%1"=="" (Call :GetArgs %*)
If %Year% LSS 1582 (Goto :EOF&Echo %~n0: Not Gregorian Calendar.>&2)
If %Year% EQU 1582 If %Month% LSS 10 (Goto :EOF
Echo %~n0: Not Gregorian Calendar.>&2)
:Repeat
If "%ym%"=="%Year%.%Month%" (Set Hoy=1) Else Set Hoy=0


If %Month:~0,1%==0 Set Month=%Month:~1%

If %Day:~0,1%==0 Set Day=%Day:~1%


For /F "tokens=%Month%" %%a in ('Echo %Months%') Do Set MonthName=%%a

For %%a in (%Monthdays%) Do Echo.%%a|FindStr/el ":%Month%">NUL:&&Set^
domz=%%a
Set /A domz=domz
If %Month% NEQ 2 Goto :NoLeap
Set /A "Leap1=year%%4,Leap2=year%%100,Leap3=year%%400"
If %Leap1% EQU 0 (Set Leap1=1) Else (Set Leap1=0)
If %Leap2% EQU 0 (Set Leap2=0) Else (Set Leap2=1)
If %Leap3% EQU 0 (Set Leap3=1) Else (Set Leap3=0)
Set /A "Leap=%Leap1% & %Leap2% | %Leap3%"
Set /A domz+=Leap
:NoLeap
Set dow#=%dow#:~0,1%
Set /A "dom1=Day-dow#,dom1%%=7,dom1=8-dom1,dom1%%=7"
Set /A i=dom1
:loop1
If %i% GTR 0 Set /A i-=1&Set blanks=%blanks% &Goto :loop1
Echo.%MonthName% %Year%
Echo.Sun Mon Tue Wed Thu Fri Sat
For /L %%a in (1,1,%domz%) Do Call :Build %%a

Set /A Month+=1
If %Month% GTR 12 (Goto :EOF)
Call :GetArgs %Year%.%Month%&Goto %Repeat%
:GetArgs
SetLocal ENABLEEXTENSIONS
Set CL=%*&Set /A i=1
Set CL=%CL:-=,%
Set CL=%CL:.=,%
Set CL=%CL:/=,%
For %%a in (%CL%) Do (Call Set dow.%%i%%=%%a&&Set /A i+=1)
If "%dow.2%"=="" (Set dow.2=1&Set Repeat=:Repeat)
If "%dow.3%"=="" Set dow.3=%Day%
Set cy=%dow.1%&Set m=%dow.2%&Set k=%dow.3%
If %m% LSS 3 Set /A cy-=1
Set c=%cy:~0,2%&Set y=%cy:~2,2%
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::Math from CRC:SMTF(30) 10.2.2 ::
:: eq 10.2.1: W=(k+[2.6m-0.2]-2C+Y+[Y/4]+[C/4]) mod 7, []=floor(). ::
Set /A m-=14,m=m%%12,m+=12& ::
Set /A w=26*m,w-=2,w/=10,w=w+k-2*c+y+y/4+c/4,w=w%%7,w+=7,w=w%%7&::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
EndLocal&Set dow#=%w%&Set Month=%dow.2%&Set Day=%dow.3%&(
Set Year=%dow.1%&Set Repeat=%Repeat%)
Goto :EOF
:::::::::::::::::::::::::::::::::::::::::::::::::
:Help
SetLocal
Set Help= /? -? /help --help &::eol
Echo.%Help%|FindStr/li /c:" %arg1% ">NUL:||(Dir>NUL:&EndLocal&Goto:EOF)
For /F "tokens=1* delims=:" %%a in ('FindStr/bli ":!" %~f0') Do Echo.%%b
EndLocal&Dir:>NUL: 2>&1
Goto :EOF
::END OF SCRIPT:::::::::::::::::::::::::::::::::::::::::::::::::::::::::

Frank

unread,
Nov 9, 2001, 10:12:12 PM11/9/01
to
Frank <01c14764$b0bf6700$0b432640@erafrbqcjahdbcys>...

^ Here's a small calendar script that prints the current month.

Here's a slightly faster version that also fixes a bug in the last version.

Frank

::START OF SCRIPT::::::::::::::::::::::::::::::::::::::::::::::::::


::Calendar.cmd
:!:Prints Gregorian Calendar (1582.10.15++) for the current month or the
:!:specified month or year.

:!:Written by Frank P. Westlake, 2001.09.25, 2001.10.29, 2001.11.09


:!:
:!:Usage: Calendar [Year[-Month]]
:!:
:!: Year The desired year, including century.
:!: Month The desired month.
:!: - A space or any of .,;/-=
:!:
:!:With no arguments, only the current month is printed. The current day
:!:is marked with an asterisk (*).
:!:
:!:Examples:
:!: Calendar
:!: Calendar 2001
:!: Calendar 2001.10
:!:
@Echo OFF&SetLocal ENABLEEXTENSIONS
Set arg1=%1&Call :Help||Goto :EOF

Goto :BeginScript
:Build
Set num=%1

If DEFINED blanks (Set Line=%blanks%&Set Blanks=)
If %num% LSS 10 Set num= %num%
Set Line=%Line%%num%

If %Hoy% EQU 1 If %num% EQU %now% Call Set Line=%%Line:^%num% =^%num%*%%


If %num% EQU %domz% Goto :Print
Set /A "test=dom1%%7,dom1+=1"
If %test% LSS 6 Set Line=%Line% &Goto :EOF
:Print
Echo.%Line%

Set Line=&Goto :EOF


:BeginScript
Set WeekDays=0:Sun,1:Mon,2:Tue,3:Wed,4:Thu,5:Fri,6:Sat
Set MonthDays=31:1,28:2,31:3,30:4,31:5,30:6,31:7^
31:8,30:9,31:10,30:11,31:12
Set Months=January February March April May June July August September^

October November December &Set Repeat=:EOF
For /F "tokens=1-4 delims=/ " %%a in ('DATE/T') Do (Set now=%%c


Set dow=%%a&Set Month=%%b&Set Day=%%c&Set Year=%%d&Set ym=%%d.%%b)

For %%a in (%Weekdays%) Do Echo.%%a|Find "%dow%">NUL:&&Set dow#=%%a

If %now:~0,1%==0 Set now=%now:~1%&If NOT "%1"=="" (Call :GetArgs %*)


If %Year% LSS 1582 (Goto :EOF&Echo %~n0: Not Gregorian Calendar.>&2)
If %Year% EQU 1582 If %Month% LSS 10 (Goto :EOF
Echo %~n0: Not Gregorian Calendar.>&2)
:Repeat
If "%ym%"=="%Year%.%Month%" (Set Hoy=1) Else Set Hoy=0

If %Month:~0,1%==0 Set Month=%Month:~1%

If %Day:~0,1%==0 Set Day=%Day:~1%


For /F "tokens=%Month%" %%a in ('Echo %Months%') Do Set MonthName=%%a

Set /A "domz=5546>>Month,domz&=1,domz+=30"


If %Month% NEQ 2 Goto :NoLeap

Set /A L1=Year%%4,L2=Year%%100,L3=Year%%400
If %L1% NEQ 0 (Set domz=28) Else If %L3% EQU 0 (Set domz=29) ^
Else If %L2% EQU 0 (Set domz=28) Else Set domz=29


:NoLeap
Set dow#=%dow#:~0,1%
Set /A "dom1=Day-dow#,dom1%%=7,dom1=8-dom1,dom1%%=7"
Set /A i=dom1
:loop1
If %i% GTR 0 Set /A i-=1&Set blanks=%blanks% &Goto :loop1
Echo.%MonthName% %Year%
Echo.Sun Mon Tue Wed Thu Fri Sat
For /L %%a in (1,1,%domz%) Do Call :Build %%a

Set /A Month+=1
If %Month% GTR 12 (Goto :EOF)
Call :GetArgs %Year%.%Month%&Goto %Repeat%
:GetArgs
SetLocal ENABLEEXTENSIONS
Set CL=%*&Set /A i=1
Set CL=%CL:-=,%
Set CL=%CL:.=,%
Set CL=%CL:/=,%
For %%a in (%CL%) Do (Call Set dow.%%i%%=%%a&&Set /A i+=1)
If "%dow.2%"=="" (Set dow.2=1&Set Repeat=:Repeat)

Set dow.3=1

Frank

unread,
Nov 20, 2001, 9:10:09 AM11/20/01
to
Frank <01c14764$b0bf6700$0b432640@erafrbqcjahdbcys>...
^ Here's a small calendar script...

I hate to post another version after seeing the output from one of Phil's
calendar scripts but my last version had bugs so I'm obligated to.
Hopefully this will be the last one.

Frank

::BEGIN SCRIPT::::::::::::::::::::::::::::::::::::::::::::


::Calendar.cmd
:!:Prints Gregorian Calendar (1582.10.15++) for the current month or the
:!:specified month or year.

:!:Written by Frank P. Westlake 2001.09.25 2001.10.29 2001.11.09 2001.11.20
:!:
:!:Usage: Calendar [Year[-Month[-Day]]]


:!:
:!: Year The desired year, including century.
:!: Month The desired month.

:!: Day Ignored but may be included.


:!: - A space or any of .,;/-=
:!:
:!:With no arguments, only the current month is printed. The current day
:!:is marked with an asterisk (*).
:!:
:!:Examples:
:!: Calendar
:!: Calendar 2001
:!: Calendar 2001.10
:!:
@Echo OFF&SetLocal ENABLEEXTENSIONS

:: Edit %WeekDays% and %Months% to suit system locale.
Set WeekDays=Sun Mon Tue Wed Thu Fri Sat
Set Months=January February March April May June July^
August September October November December
Goto :BeginScript
:Build
Set num=%1&If DEFINED blanks (Set Line=%blanks%&Set Blanks=)


If %num% LSS 10 Set num= %num%
Set Line=%Line%%num%

If %CM% EQU 1 If %num% EQU %hoy% Call Set Line=%%Line:^%num% =^%num%*%%


If %num% EQU %domz% Goto :Print

Set/A "test=domL%%7,domL+=1"


If %test% LSS 6 Set Line=%Line% &Goto :EOF
:Print

Echo.%Line%&Set Line=&Goto :EOF
:BeginScript :::::::::::::::::::::::::::::::::::::::::::::::::::::::::


Set arg1=%1&Call :Help||Goto :EOF

Set Repeat=:EOF&Set /A i=0,g=1582
Set E1=(Echo %~n0: Not Gregorian Calendar.^>^&2^&Goto :EOF)


For /F "tokens=1-4 delims=/ " %%a in ('DATE/T') Do (

Set dow=%%a&Set Month=%%b&Set Day=%%c&Set Year=%%d&Set ym=%%d.%%b)

If "%Day:~0,1%"=="0" (Set hoy=%Day:~1%) Else (Set hoy=%Day%)
For %%a in (%Weekdays%) Do If %%a==%dow% (Set/a dow#=i) Else Set/A i+=1


If NOT "%1"=="" (Call :GetArgs %*)

If %Month% GTR 12 (%E1%) Else If %Year% LSS %g% (%E1%) Else (
If %Year% EQU %g% If %Month% LSS 10 %E1%)
:Repeat
If "%ym%"=="%Year%.%Month%" (Set CM=1) Else (Set CM=0)


If %Month:~0,1%==0 Set Month=%Month:~1%

If %Day:~0,1%==0 Set Day=%Day:~1%
For /F "tokens=%Month%" %%a in ("%Months%") Do Set MonthName=%%a
Set /A "domz=5546>>Month,domz&=1,domz+=30"


If %Month% NEQ 2 Goto :NoLeap

Set /A L1=Year%%4,L2=Year%%100,L3=Year%%400
If %L1% NEQ 0 (Set domz=28) Else If %L3% EQU 0 (Set domz=29) ^
Else If %L2% EQU 0 (Set domz=28) Else Set domz=29
:NoLeap

Set/A "domL=Day-dow#,domL%%=7,domL=8-domL,domL%%=7"
Set/A i=domL
:loop1
If %i% GTR 0 (Set /A i-=1&Set blanks=%blanks% &Goto :loop1)
Echo.%MonthName% %Year%&Echo.%WeekDays%


For /L %%a in (1,1,%domz%) Do Call :Build %%a

If "%Repeat%"==":EOF" (Goto :EOF) Else If %Month% GEQ 12 (Goto :EOF) ^
Else (Set /A Month+=1&Echo.)
Call :GetArgs %Year%.%Month%&Goto :Repeat


:GetArgs
SetLocal ENABLEEXTENSIONS
Set CL=%*&Set /A i=1
Set CL=%CL:-=,%
Set CL=%CL:.=,%
Set CL=%CL:/=,%
For %%a in (%CL%) Do (Call Set dow.%%i%%=%%a&&Set /A i+=1)
If "%dow.2%"=="" (Set dow.2=1&Set Repeat=:Repeat)

Set cy=%dow.1%&Set m=%dow.2%&Set k=1


If %m% LSS 3 Set /A cy-=1
Set c=%cy:~0,2%&Set y=%cy:~2,2%

Set /A m-=14,m=m%%12,m+=12
::From CRC:SMTF(30) 10.2.2 eq 10.2.1:
Set /A w=26*m,w-=2,w/=10,w=w+k-2*c+y+y/4+c/4,w=w%%7,w+=7,w=w%%7
EndLocal&Set dow#=%w%&Set Month=%dow.2%&Set Day=%k%&(


Set Year=%dow.1%&Set Repeat=%Repeat%)
Goto :EOF
:::::::::::::::::::::::::::::::::::::::::::::::::
:Help
SetLocal
Set Help= /? -? /help --help &::eol
Echo.%Help%|FindStr/li /c:" %arg1% ">NUL:||(Dir>NUL:&EndLocal&Goto:EOF)
For /F "tokens=1* delims=:" %%a in ('FindStr/bli ":!" %~f0') Do Echo.%%b
EndLocal&Dir:>NUL: 2>&1
Goto :EOF

::END SCRIPT::::::::::::::::::::::::::::::::::::::::::::::

Phil Robyn

unread,
Nov 21, 2001, 12:22:24 AM11/21/01
to

Hey, Frank,

This is very nice! Fast, too! Thanks for posting it.

Reply all
Reply to author
Forward
0 new messages