How to produce a Year-to-a-page calendar

Tony Marston - 1st June 2002

Many years ago I wrote a simple COBOL program which would print a calendar showing all the dates within a particular year so I could quickly identify on which day of the week each date fell. The printed output looked like the following:-

tip31_01.gif

I later decided to try and code it in Uniface just to see how easy (or difficult) it was. Due to the fact that Uniface contains some very nifty date functions it was surprisingly simple. My COBOL version was more complicated as I had to create my own set of date manipulation routines.

The structure of the CALENDAR form is as follows:-

  1. There is a DUMMY entity at the top with a field into which the year number can be entered.
  2. Below this is an entity called MONTH which is 28 cells wide by 12 cells deep. It has four occurrences going across the screen and three going down the screen. This produces an array containing all 12 months. At the top of each MONTH is a NAME field into which the month name is supplied at runtime.
  3. Within the MONTH entity is an entity called WEEK which is 4 cells wide by 9 cells deep. This has six occurrences going across the screen. This entity contains 7 fields named MON, TUE, WED, THU, FRI, SAT and SUN, with a final field at the bottom named WEEK_NO.
  4. With some text labels running down the left-hand edge the final structure looks like this:-

tip31_02.gif

After a YEAR number has been entered the code which fills the structure with data looks something like this:

entry BUILD_CALENDAR
params
   numeric pi_Year    : IN
endparams
variables
   date    lv_Date
   numeric lv_Year, lv_Month, lv_Day
   numeric lv_DayOfWeek
endvariables

call CREATE_MONTHS                    ; insert name of each month

lv_Date = $date("01/01/%%pi_Year")    ; get first day of the year

lv_Year = year.dummy
setocc "month",1                      ; start at month 1
setocc "week",1                       ; start at week 1

while (lv_Year = pi_Year)

   lv_Day       = lv_Date[D]          ; extract day
   lv_DayOfWeek = lv_Date[A]          ; extract day-of-week
   week_no.week = lv_Date[W]          ; extract week number
   
   ; set day number into day-of-week for current week
   selectcase lv_DayOfWeek
      case 1
         monday.week    = lv_Day
      case 2
         tuesday.week   = lv_Day
      case 3
         wednesday.week = lv_Day
      case 4
         thursday.week  = lv_Day
      case 5
         friday.week    = lv_Day
      case 6
         saturday.week  = lv_Day
      case 7
         sunday.week    = lv_Day
   endselectcase

   ; after day 7 increment to following week
   if (lv_DayOfWeek = 7) creocc "week",-1

   lv_Date  = lv_Date + 1d            ; increment date by 1 day

   lv_Month = lv_Date[M]              ; extract month

   ; check for change of month
   if (lv_Month != $curocc(month))
      setocc "month",lv_Month         ; next month
      setocc "week",1                 ; start at week 1
      lv_Year  = lv_Date[Y]           ; extract year
   endif

endwhile

end ; BUILD_CALENDAR

The actual code which I use can be downloaded from here.


Tony Marston
1st June 2002

mailto:tony@tonymarston.net
mailto:TonyMarston@hotmail.com
http://www.tonymarston.net

counter