Highlighted
Absent Member.
Absent Member.
1619 views

[archive] Algorithm for Converting Gregorian Dates to ISO 8601 Week number

[Migrated content. Thread originally posted on 17 June 2003]

Some time ago I needed to compute a week number for a date. I found the site http://personal.ecu.edu/mccartyr/ISOwdALG.txt wich describes an algorithm for converting Gregorian Dates to ISO 8601 Week Date.

I converted this algorithm in COBOL and decided to share this with all of you.

Andr? Mathlener
0 Likes
1 Reply
Highlighted
Absent Member.
Absent Member.

RE: [archive] Algorithm for Converting Gregorian Dates to ISO 8601 Week number

Sorry. I noticed the attachment was missing. In case the uploading goes wrong again, I also put the source in this message.




       identification division.
       program-id.   Weekno.

      *Algorithm for Converting Gregorian Dates to ISO 8601 Week Date
      *See [url]http://personal.ecu.edu/mccartyr/ISOwdALG.txt[/url]

       environment      division.
       configuration    section.

       input-output section.
       file-control.

       data division.
       file section.

       working-storage section.
       01  the-date                    pic 9(08).
       01  the-date-r redefines the-date.
           03  the-year                pic 9(04).
           03  the-month               pic 9(02).
           03  the-day                 pic 9(02).
       77  the-date-save               pic 9(08).

       77  day-index                   pic 9(01).
       77  no-of-days                  pic 9(03).
       77  tmp-days                    pic 9(03).
       77  tmp-div                     pic 9(08).
       77  weekyear                    pic 9(04).
       77  weekno                      pic 9(02).
       77  day-index-jan-1st           pic 9(01).
       77  leap-year                   pic 9(01).
       77  leap-year-1                 pic 9(01).
       77  mod-rem                     pic 9(03).
       77  int-ymd                     pic 9(08).

       01  month-table1.
           03  filler                  pic 9(03) value 0.
           03  filler                  pic 9(03) value 31.
           03  filler                  pic 9(03) value 59.
           03  filler                  pic 9(03) value 90.
           03  filler                  pic 9(03) value 120.
           03  filler                  pic 9(03) value 151.
           03  filler                  pic 9(03) value 181.
           03  filler                  pic 9(03) value 212.
           03  filler                  pic 9(03) value 243.
           03  filler                  pic 9(03) value 273.
           03  filler                  pic 9(03) value 304.
           03  filler                  pic 9(03) value 334.

       01  days-to-month-table redefines month-table1.
           03  days-to-month           pic 9(03) occurs 12.


       procedure division.
       main.
           accept the-date from century-date
           perform compute-weekno
           display "Current weekno: " weekno

           accept omitted

           goback
           .

       leap-year-check.
           move 0 to leap-year
           divide the-year by 4
                  giving tmp-div remainder mod-rem
           if  mod-rem = 0
               move 1 to leap-year
               divide the-year by 100
                      giving tmp-div remainder mod-rem
               if  mod-rem = 0
                   move 0 to leap-year
                   divide the-year by 400
                          giving tmp-div remainder mod-rem
                   if  mod-rem = 0
                       move 1 to leap-year
                   end-if
               end-if
           end-if
           .

       compute-weekno.
           move the-date      to the-date-save

      *    Is previous year a leap year?
           subtract 1 from the-year
           perform leap-year-check
           move leap-year to leap-year-1

      *    Is this year a leap year?
           add 1 to the-year
           perform leap-year-check

           initialize no-of-days
      *    Add in # of days in preceeding months
           add days-to-month(the-month) to no-of-days

           if  leap-year = 1 and the-month > 2
               add 1 to no-of-days
           end-if

      *    Add in day within month
           add the-day to no-of-days

      *    What day is jan 1st of this year?
           move 1             to the-day, the-month
           perform compute-weekday
           move day-index     to day-index-jan-1st
           move the-date-save to the-date

      *    What weekday is this day?
           perform compute-weekday

      *    Find if date falls in previous year, week 52 or 53
           if  no-of-days <= (8 - day-index-jan-1st)
           and day-index-jan-1st > 4
               subtract 1 from the-year giving weekyear
               if  day-index-jan-1st = 5
               or  (day-index-jan-1st = 6 and leap-year-1 = 1)
                   move 53 to weekno
               else
                   move 52 to weekno
               end-if
           else
               move the-year to weekyear
           end-if

      *    Find if date falls in next year, week 1
           if  weekyear = the-year
               if  leap-year = 1
                   move 366 to tmp-days
               else
                   move 365 to tmp-days
               end-if
               if  (tmp-days - no-of-days) < (4 - day-index)
                   add 1 to weekyear
                   move 1 to weekno
               end-if
           end-if

      *    Find if date falls in current year, week 1 - 53
           if  weekyear = the-year
               compute tmp-days =
                       no-of-days + ( 7 - day-index) +
                       (day-index-jan-1st - 1)
               compute weekno = tmp-days / 7
               if  day-index-jan-1st > 4
                   subtract 1 from weekno
               end-if
           end-if
           .

       compute-weekday.
           move function integer-of-date(the-date) to int-ymd
           divide int-ymd by 7 giving tmp-div remainder day-index

           if  day-index = 0
               move 7 to day-index
           end-if
           .
0 Likes
The opinions expressed above are the personal opinions of the authors, not of Micro Focus. By using this site, you accept the Terms of Use and Rules of Participation. Certain versions of content ("Material") accessible here may contain branding from Hewlett-Packard Company (now HP Inc.) and Hewlett Packard Enterprise Company. As of September 1, 2017, the Material is now offered by Micro Focus, a separately owned and operated company. Any reference to the HP and Hewlett Packard Enterprise/HPE marks is historical in nature, and the HP and Hewlett Packard Enterprise/HPE marks are the property of their respective owners.