<

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x

Gregorian Calendar for Windows Command Prompt

Published on
13,782 Points
7,782 Views
Last Modified:
Approved
If like me you are one who spends a lot of time working and scripting with cmd.exe, sometimes it is handy to be able to quickly view a calendar for a given month and year. This script will quickly do just that!  Save the code posted below to a .bat file called gcal.bat.  Then you will be able to view the current calendar (default) or specify a month and year, all with a simple command:

  gcal  [month]  [YYYY]

Examples:

  gcal  July
  gcal  August 2012
  gcal  09 2012
  gcal  10/2012
  gcal  nov .  dec .  jan 2013


Notes:  This is a pure script solution - no additional third party tools or scripts are required.  (EDIT: I now use the wmic program that comes with the OS to get the default month and year in a regionally non-dependant manner, but I left the "pure script" version in for reference, and for use with older OS versions.  See the formatParams section.)

The script is divided into four sections.  The first section (formatParams) validates and formats the input parameters (if any).  For flexibility the script will take various month formats.  The years is always a number from 1-9999.

The second section (getDayList) simply builds a string of numbers to represent the days in the specified month, 1 - 28, 29, 30, or 31 as required.

The third section (getSTARTDOW) actually does the work - determining which day of the week is the first of the month specified.

The fourth section (displayCalendar) displays the calendar by pulling sub-strings from the data build in section 2 - one for each week of the month.

Finally, it should be noted that the Gregorian calendar was first adapted in 1582, and gained widespread acceptance in 1752.  Therefore, renderings of the Gregorian calendar prior to these dates are just projections.

Edit 2016-02-01 - added a feature to surround the current day in brackets when the current month is rendered. Also some minor bug fixes.

Now the script!

gcal.bat
@echo off
 setlocal DISableDelayedExpansion

:REM      gcal.bat - Gregorian Calendar
:REM      written by:  Ralph L. Brown
:REM      syntax: gcal.bat [month] [YYYY] ...

:START

@echo.
 set params=%~1/%~2
 set params=%params:/= %
 set params=%params:-= %

 call :formatParams %params%  ||  exit/b 1
 call :getDayList
 call :getSTARTDOW
 call :displayCalendar

 set _p1=%~1
 if "%_p1%" == "%_p1:/=%" shift /1
 shift /1
 if not "%1"=="" goto :START

 exit/b 0

:END MAIN





:formatParams - This section validates the month and year parameters (if supplied).

 set currentDate=%date:~10,4%%date:~4,2%%date:~7,2%
 set/a currentDate+=0 2>nul

 REM - if the above fails, then get these fields using a regionally independent method:
 if NOT "%currentDate%"=="%date:~10,4%%date:~4,2%%date:~7,2%"  for /f "delims= " %%C in ('wmic path Win32_LocalTime Get Day^,Month^,Year /Format:List 2^>nul ^| find "="') do @(set current%%C) 2>nul

 REM - but this way is generally faster...
 if not defined currentYear   set/a currentYear=%currentDate:~0,4%
 if not defined currentMonth  set/a currentMonth=%currentDate:~0,6% %% %currentDate:~0,4%00
 if not defined currentDay    set/a currentDay=%currentDate% %% %currentDate:~0,6%00


 call :decode  "%currentMonth%"   "1:JAN,JAN:JAN,2:FEB,FEB:FEB,3:MAR,MAR:MAR,4:APR,APR:APR,5:MAY,MAY:MAY,6:JUN,JUN:JUN,7:JUL,JUL:JUL,8:AUG,AUG,08:AUG,AUG:AUG,9:SEP,SEP,09:SEP,SEP:SEP,10:OCT,OCT:OCT,11:NOV,NOV:NOV,12:DEC,DEC:DEC"
 set currentMonth=%decode%

 set/a calMonth=%~1 2>nul  ||  set calMonth=%~1
 if 0%calMonth% equ 0 set calMonth=%~1
 if "%calMonth%"==""  set calMonth=%currentMonth%
 if "%calMonth%"=="." set calMonth=%currentMonth%


 call :decode  "%calMonth:~0,3%"  "1:JAN,JAN:JAN,2:FEB,FEB:FEB,3:MAR,MAR:MAR,4:APR,APR:APR,5:MAY,MAY:MAY,6:JUN,JUN:JUN,7:JUL,JUL:JUL,8:AUG,AUG,08:AUG,AUG:AUG,9:SEP,SEP,09:SEP,SEP:SEP,10:OCT,OCT:OCT,11:NOV,NOV:NOV,12:DEC,DEC:DEC"
 set calMonth=%decode%

 if not defined calMonth call :syntax Invalid month specified: "%~1"\n Valid range is 1-12, or month name (or abbreviation), or . for current month. || exit/b 1


 set calYear=%~2
 if "%calYear%"=="." set calYear=
 if defined calYear  set calYear=%calYear:X=#%
 if defined calYear  set/a calYear=%calYear% 2>nul
 if defined calYear  if NOT "%calYear%"=="%~2"  set calYear=INVALID
 for %%Y in (00,01,02,03,04,05,06,07,08,09) do if "%~2"=="%%Y" set calYear=%currentYear:~0,2%%%Y
 if NOT defined calYear set calYear=%currentYear%

 REM - Comment-out the next 2 lines if you want to render years 1 A.D. - 99 A.D.
 if %calYear% LSS    10 set calYear=%currentYear:~0,2%0%calYear%
 if %calYear% LSS   100 set calYear=%currentYear:~0,2%%calYear%

 if %calYear% LSS 10000 if %calYear% GEQ 0 exit/b 0

 call :syntax Invalid year specified: "%~2"\n Valid range is 100 - 9999, or . for current year.
 exit/b 1
:END-formatParams





:getDayList - This section creates the string of days for the specified month.
 set/a leapYear= !(%calYear% %% 4) - !(%calYear% %% 100) + !(%calYear% %% 400) 2>nul
 set dayList=++++++1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28
 if "%calMonth%"=="FEB"  if %leapYear% equ 1  set dayList=%dayList%  29
 if not "%calMonth%"=="FEB"  set dayList=%dayList%  29  30
 for %%M in (JAN,MAR,MAY,JUL,AUG,OCT,DEC) do if "%calMonth%"=="%%M"  set dayList=%dayList%  31
 set dayList=%dayList:+=     % 
 if %currentYear% equ %calYear%  if "%currentMonth%"=="%calMonth%"  call set dayList=%%dayList: %currentDay% =[%currentDay%]%%
 exit/b %errorlevel%
:END-getDayList





:getSTARTDOW - This section determines which day of the week falls on the 1st of the month (0 - 6 for Sun - Sat).
 set/a workYear=%calYear% %% 400 2>nul
 set/a DOWJAN1= ( ( ( %workYear% %% 28 ) + ( ( (%workYear%+3) %% 28) / 4 ) ) + (( 6 * ( 1 + ((%workYear%-1) / 100)) ) ) ) %% 7
 for %%M in (JAN,FEB) do if "%calMonth%"=="%%M"  set leapYear=0
 call :decode  "%calMonth%"  "JAN:0,FEB:3,MAR:3,APR:6,MAY:1,JUN:4,JUL:6,AUG:2,SEP:5,OCT:0,NOV:3,DEC:5"
 set/a STARTDOW= ( %DOWJAN1% + %decode% + %leapYear% ) %% 7
 exit/b %errorlevel%
:END-getSTARTDOW





:displayCalendar - This section displays the calendar.
 set calYear=    %calYear%||:This is to format the year for display.
@echo.          %calMonth%  %calYear:~-4%
@echo. Sun Mon Tue Wed Thu Fri Sat
@echo.
 for /L %%W in (1,1,6) do  call :writeWeek %%W

 if %calYear% GTR 1752 exit/b %errorlevel%
@echo. NOTE: The Gregorian calendar was first adapted in 1582, but
@echo. only gained widespread acceptance in 1752.  The calendar
@echo. above is a projection of how the Gregorian calendar would 
@echo. have rendered had it been in use prior to September of 1752.
 exit/b %errorlevel%
:END-displayCalendar





:writeWeek - This section extracts the specified week from the dayList string.
 set/a _idx=%1*28-4*%STARTDOW%
 call set week=%%dayList:~%_idx%,28%%
@echo.%week%
 exit/b 0
:END-writeWeek





:decode - This function extracts the matching key value from the supplied map.
 set key=%~1
 set csvmap=,%~2
 set ret=%~3
 if "%ret%"=="" set ret=decode
 call set key=%%csvmap:*,%key%:=%%
 set %ret%=%key:,=&:%||exit/b 1
 exit/b 0
:END-decode





:syntax
 set msg=%*
@echo. %msg:\n=&@echo.%
@echo.
@echo. Syntax:   %~nx0  [month] [YYYY] ...
@echo. Example:  %~nx0  July
@echo. Example:  %~nx0  August %currentYear%
@echo. Example:  %~nx0  09 %currentYear%
@echo. Example:  %~nx0  10/%currentYear%
 set/a currentYear+=1
@echo. Example:  %~nx0  nov . dec . jan %currentYear%
 exit/b 1
:END-syntax

Open in new window

0
Comment
1 Comment

Expert Comment

by:Oleg Aney
Good script! I'll be using it in one of my powershell programmes.
1

Featured Post

CompTIA Security+

Learn the essential functions of CompTIA Security+, which establishes the core knowledge required of any cybersecurity role and leads professionals into intermediate-level cybersecurity jobs.

Join & Write a Comment

If you, like me, have a dislike for using Online Subscription anti-spam services, then this video series is for you. I have an inherent dislike of leaving decisions such as what is and what isn't spamming to other people or services for me and insis…
This is Part-2 of Learning to use the Power of Mailwasher Pro so if you haven't watched Part-1 yet, I urge you to do so before watching this video. Click this link to watch Part-1 (https://www.experts-exchange.com/videos/56638/Learn-to-use-the-POWER…

Keep in touch with Experts Exchange

Tech news and trends delivered to your inbox every month