View Full Version : Algorithm for Converting Gregorian Dates to ISO 8601 Week number
mathlener
06-17-2003, 05:17 AM
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
mathlener
06-18-2003, 06:19 AM
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 http://personal.ecu.edu/mccartyr/ISOwdALG.txt
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
.
vBulletin® v3.6.8, Copyright ©2000-2010, Jelsoft Enterprises Ltd.