Hello Hume,
Don Libes <libes@cme.nist.gov> has pointed me to you directly... i had mentioned that the ISO week of Jan 1 was never 52 with the code he'd had, although just over 1 time in 7 it should be. he got new code from you, which seems to have the right week for Jan 1 but not always Dec 1 - it should sometimes be in week 1 of "next" year...
e.g. 1973 Dec 31 should be in week 1 of 1974.
I think I disagree rather strongly with this. Dec 31 should always be in the last week of the year. This just makes sense. The question is whether it's week 52 or week 53. Unless the ISO standard actually *says* that it's in week 1 of the following year, I don't want to change my code... (And if it does say that, then In My Not So Humble Opinion it's silly.)
i've taken a very different technique for calculating ISO week numbers in some code of my own. (i was comparing it to expect's timestamp, which uses your code, and the calendar stuff in emacs 19.30) although it's only designed to work for 100 years (i assume a leap year every four years, so after 2100 Feb 28 i'll be a day off, etc), it's so much simpler you may want to adapt/adopt it...
x = ut/(60*60*24) number of days = unix time / length of day x = x + 3 adjust to the previous monday ISOday = 1 + x%7 weekday x = x/7 number of weeks y = (28*x+2)/1461 number of years x = x - (1461*y+25)/28 number of weeks into year ISOyear = 1970+y ISOweek = 1+x
(the divisions should be C integer divisions)
the best way to fix it for the rest of the gregorian cycle is probably to change the 2 and the 25. note that whatever they're changed to, must sum to 27. (if you're interested in this method, i'll try to complete it for you if you'd prefer...) -- Hume Smith <hclsmith@isisnet.com> NetBSD r00lz :)
Real Americans don't carry cash. Their police may steal it.d
Ado and Tor, comments? ... ===============================================================================
I think I disagree rather strongly with this. Dec 31 should always be in the last week of the year. This just makes sense. The question is whether it's week 52 or week 53.
Ado and Tor, comments?
Sorry, you are wrong here. For example, week 1 of 1997 starts on Mon, Dec 30, 1996. Look in any European (or at least Nordic) calendar for verification. Each week has one well-defined number, which around New Year might be the last week of the previous year, or week 1 of the following year. ... ===============================================================================
Me:
I think I disagree rather strongly with this. Dec 31 should always be in the last week of the year. This just makes sense. The question is whether it's week 52 or week 53.
Ado and Tor, comments?
Tor:
Sorry, you are wrong here. For example, week 1 of 1997 starts on Mon, Dec 30, 1996. Look in any European (or at least Nordic) calendar for verification. Each week has one well-defined number, which around New Year might be the last week of the previous year, or week 1 of the following year.
Sigh. Not what I wanted to hear (TM). Oh well. I'll take a look at my code and see what I can do about this. (Tor, any code suggestions? :-) ... ===============================================================================
Me:
I think I disagree rather strongly with this. Dec 31 should always be in the last week of the year. This just makes sense.
so does having Jan 1 in the first week of next year, but that doesn't seem to be the way it works. ISO's concerned with a week-oriented calendar, the week being the one cycle which has dominated Western civilisation unchanged for millenia. a better person to ask this may be Eduard Rheingold <rheingold@cs.uiuc.edu> - he wrote the emacs 19.30 calendar package which has been my reference.
Sigh. Not what I wanted to hear (TM). Oh well. I'll take a look at my code and see what I can do about this. (Tor, any code suggestions? :-)
well, i'm not tor, but i'll tell you what i did. compute an absolute week number, work out what year it's in, work out what week that year starts. it's very simple for any part of the calendar not involving the Gregorian correction, and right now we're in the middle of a 200-year span not affected by it. it takes two calculations, both of the form (Ax+B)/C. no branches, no loops... it really can't get much simpler. it's possible that the same thing will work for a complete Gregorian cycle, changing A to 20871, C to 400, and B to something, but i haven't tried it yet (i need to work out all the numbers with another method before i can try to find a B). ... =============================================================================== SCCS/s.strftime.c: 7.38 vs. 7.42 *** 7.38/strftime.c Tue Jan 2 17:21:43 1996 --- 7.42/strftime.c Tue Jan 2 17:21:44 1996 *************** *** 1,6 **** #ifndef lint #ifndef NOID ! static char elsieid[] = "@(#)strftime.c 7.38"; /* ** Based on the UCB version with the ID appearing below. ** This is ANSIish only when "multibyte character == plain character". --- 1,6 ---- #ifndef lint #ifndef NOID ! static char elsieid[] = "@(#)strftime.c 7.42"; /* ** Based on the UCB version with the ID appearing below. ** This is ANSIish only when "multibyte character == plain character". *************** *** 296,361 **** "%d", pt, ptlim); continue; case 'V': ! /* ! ** From Arnold Robbins' strftime version 3.0: ! ** "the week number of the year (the first ! ** Monday as the first day of week 1) as a ! ** decimal number (01-53). The method for ! ** determining the week number is as specified ! ** by ISO 8601 (to wit: if the week containing ! ** January 1 has four or more days in the new ! ** year, then it is week 1, otherwise it is ! ** week 53 of the previous year and the next ! ** week is week 1)." ! ** (ado, 5/24/93) ! */ ! /* ! ** XXX--If January 1 falls on a Friday, ! ** January 1-3 are part of week 53 of the ! ** previous year. By analogy, if January ! ** 1 falls on a Thursday, are December 29-31 ! ** of the PREVIOUS year part of week 1??? ! ** (ado 5/24/93) ! */ ! /* ! ** You are understood not to expect this. ! */ { ! int i; ! i = (t->tm_yday + 10 - (t->tm_wday ? ! (t->tm_wday - 1) : 6)) / 7; ! if (i == 0) { /* ! ** What day of the week does ! ** January 1 fall on? */ ! i = t->tm_wday - ! (t->tm_yday - 1); /* ! ** Fri Jan 1: 53 ! ** Sun Jan 1: 52 ! ** Sat Jan 1: 53 if previous ! ** year a leap ! ** year, else 52 */ ! if (i == TM_FRIDAY) ! i = 53; ! else if (i == TM_SUNDAY) ! i = 52; ! else i = isleap(t->tm_year + ! TM_YEAR_BASE) ? ! 53 : 52; ! #ifdef XPG4_1994_04_09 ! /* ! ** As of 4/9/94, though, ! ** XPG4 calls for 53 ! ** unconditionally. ! */ ! i = 53; ! #endif /* defined XPG4_1994_04_09 */ } ! pt = _conv(i, "%02d", pt, ptlim); } continue; case 'v': --- 296,366 ---- "%d", pt, ptlim); continue; case 'V': ! /* ! ** From Arnold Robbins' strftime version 3.0: "the week number of the ! ** year (the first Monday as the first day of week 1) as a decimal number ! ** (01-53)." ! ** (ado, 1993-05-24) ! ** ! ** From "http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html" by Markus Kuhn: ! ** "Week 01 of a year is per definition the first week which has the ! ** Thursday in this year, which is equivalent to the week which contains ! ** the fourth day of January. In other words, the first week of a new year ! ** is the week which has the majority of its days in the new year. Week 01 ! ** might also contain days from the previous year and the week before week ! ** 01 of a year is the last week (52 or 53) of the previous year even if ! ** it contains days from the new year. A week starts with Monday (day 1) ! ** and ends with Sunday (day 7). For example, the first week of the year ! ** 1997 lasts from 1996-12-30 to 1997-01-05..." ! ** (ado, 1996-01-02) ! */ { ! int year; ! int yday; ! int wday; ! int w; ! year = t->tm_year + TM_YEAR_BASE; ! yday = t->tm_yday; ! wday = t->tm_wday; ! for ( ; ; ) { ! int len; ! int bot; ! int top; ! ! len = isleap(year) ? ! DAYSPERLYEAR : ! DAYSPERNYEAR; /* ! ** What yday (-3 ... 3) does ! ** the ISO year begin on? */ ! bot = ((yday + 11 - wday) % ! DAYSPERWEEK) - 3; /* ! ** What yday does the NEXT ! ** ISO year begin on? */ ! top = bot - ! (len % DAYSPERWEEK); ! if (top < -3) ! top += DAYSPERWEEK; ! top += len; ! if (yday >= top) { ! w = 1; ! break; ! } ! if (yday >= bot) { ! w = 1 + ((yday - bot) / ! DAYSPERWEEK); ! break; ! } ! --year; ! yday += isleap(year) ? ! DAYSPERLYEAR : ! DAYSPERNYEAR; } ! pt = _conv(w, "%02d", pt, ptlim); } continue; case 'v':
participants (3)
-
arnold@skeeve.atl.ga.us -
Hume Smith -
Tor Lillqvist