The split week at the end of the year creates the problem. 2003-12-29 will be the first day of first week in 2004, 2004-W01-1. January dates also switch years.

The ISO standard puts days in a different week year than the calendar year.

| 28 | 29 | 30 | 31 | 01 | 02 | 03 | January dates are part of the previous year.

| 29 | 30 | 31 | 01 | 02 | 03 | 04 | December dates are part of the following years.

Converting from Week dates to Calendar dates is simple. The conversion from Calendar dates to Week dates is difficult.

Most computers have a method of converting calendar date to integer number of days.

You can use the Julian days in C in the DATLIB library. I customized my own to for internal format YYYYMMDDhhmmssffffffffffff necessary for Universal Time offset conversion and fractions of seconds.

Function #JDN@DAT convert a Calendar Date to Julian Day

Function @DAT#JND converts a Julian Day to a Calendar Date

Julian Days are integer days starting from using Proleptic calendars 4712 -01-01 BC Julian, 4713-11-24 BC Gregorian. 2003-01-01 is 245,261days after the first day. The formulas are on the Internet under Julian Days (not Julian Date) copies included at the end of the report.

This are free for personal or use. Calculations must be integers, unless stated otherwise.

Get Julian day for current calendar day.

Eval cljd# = #JDN@DAT(cldt)

Get day of week %INT makes sure intermediate values are whole number, no decimals fractions

Eval dow# = (cljd# - (%INT((cljd#/7) * 7) + 1

Convert to decimal

Eval wkdk# = dow#

Get the first day of the week for the calendar date.

Eval cljd# = cljd# - dow# + 1

Get year of week, Most days OK Convert to decmal.

Eval wkyy# = clyy#

If clmd# < 0104 or clmd# > 1228

Execute subroutine for exceptions

Exsr excyrsr

End

Determine first day of week first week.

Eval wkjd# = #JDN@DAT( whyy + '-01-04')

Eval dow# = (wkjd# - (%INT((wkjd#/7) * 7) + 1

Eval wkjd# = wkjd# - dow# +1

Get week of year

Difference of days between calendar first day of week and first day of first week

Eval woy# = %int(cljd# - wkjd#)/7) -1

Convert to decimal

Eval wkyr# = woy#

Subroutine of exceptions

excyrsr Begsr

If clmd# < 0104

If last half of the week

If wkdw# > 4

Eval wkyy# = cly# -1

Else

If first day is first half of the week

If wkdw# < 1

and (clmd# > 1228

or clmd# > 1229

or clmd# > 1230)

Eval wkyy# = clyy# +1

End

Convert Week date to Calendar date.

Determine first day of first week

Eval wkjd# = #JDN@DAT(wkyy + -01:04')

Determine day of week

Eval dow# = (wkjd# - (%INT(wkjd#/7) * 7)) +1

Get first day of week

Eval wkjd# = wkjd# - dow#

Get Calendar Julian days , convert weeks to days and add day of week

Eval cljd# = wkjd# + (wkww# -1) * 7 ) +1 + wkdw#

Get Calendar Date from Julian Date

Eval cldt = @dat#JDN)cljd#)

In 1968 in a letter to the editor of Communications of the ACM (CACM, volume 11, number 10, October 1968, p.657) Henry F. Fliegel and Thomas C. Van Flandern presented computational algorithms to convert between Julian day numbers and Gregorian dates.

The Julian day (jd) is computed from Gregorian day, month and year (d, m, y) as follows:

jd = ( 1461 * ( y + 4800 + ( m - 14 ) / 12 ) ) / 4 +

( 367 * ( m - 2 - 12 * ( ( m - 14 ) / 12 ) ) ) / 12 -

( 3 * ( ( y + 4900 + ( m - 14 ) / 12 ) / 100 ) ) / 4 +

d - 32075

Division is to be understood as in integer arithmetic, with the remainders discarded (use INT with division).

Converting from the Julian day to the Gregorian day is performed thus:

l = jd + 68569

n = ( 4 * l ) / 146097

l = l - ( 146097 * n + 3 ) / 4

i = ( 4000 * ( l + 1 ) ) / 1461001 (that's 1,461,001)

l = l - ( 1461 * i ) / 4 + 31

j = ( 80 * l ) / 2447

d = l - ( 2447 * j ) / 80

l = j / 11

m = j + 2 - ( 12 * l )

y = 100 * ( n - 49 ) + i + l (that's a lower-case L)