Merged in better support of ISO 8601 from elsie.nci.nih.gov.

Added the conversion specifiers %g and %G, that are replaced
by the year which contains the greater part of the week in question.
This commit is contained in:
Wolfgang Helbig 1997-10-03 19:06:57 +00:00
parent ab215c6703
commit b9b51fb731
2 changed files with 119 additions and 63 deletions
lib/libc/stdtime

@ -35,7 +35,7 @@
.\"
.\" @(#)strftime.3 8.1 (Berkeley) 6/4/93
.\"
.Dd June 4, 1993
.Dd October 4, 1997
.Dt STRFTIME 3
.Os
.Sh NAME
@ -113,6 +113,14 @@ representations.
.It Cm %e
is replaced by the day of month as a decimal number (1-31); single
digits are preceded by a blank.
.It Cm \&%G
is replaced by a year as a decimal number with century.
This year is the one that contains the greater part of
the week (Monday as the first day of the week).
.It Cm %g
is replaced by the same year as in
.Dq Li %G ,
but as a decimal number without century (00-99).
.It Cm \&%H
is replaced by the hour (24-hour clock) as a decimal number (00-23).
.It Cm %h
@ -164,9 +172,10 @@ the week) as a decimal number (00-53).
is replaced by the weekday (Monday as the first day of the week)
as a decimal number (1-7).
.It Cm \&%V
is replaced by the week number of the year (the first
Monday as the first day of week 1) as a
decimal number (01-53).
is replaced by the week number of the year (Monday as the first day of
the week) as a decimal number (01-53). If the week containing January
1 has four or more days in the new year, then it is week 1; otherwise
it is the last week of the previous year, and the next week is week 1.
.It Cm %v
is equivalent to
.Dq Li %e-%b-%Y .
@ -205,9 +214,34 @@ The
.Fn strftime
function
conforms to
.St -ansiC .
The
.Ql %s
conversion specification is an extension.
.St -ansiC
with a lot of extensions including
.Ql %C ,
.Ql %D ,
.Ql %E* ,
.Ql %e ,
.Ql %G ,
.Ql %g ,
.Ql %h ,
.Ql %k ,
.Ql %l ,
.Ql %n ,
.Ql %O* ,
.Ql \&%R ,
.Ql %r ,
.Ql %s ,
.Ql \&%T ,
.Ql %t ,
.Ql %u ,
.Ql \&%V ,
.Ql %+ .
The peculiar week number and year occuring in the replacements of
.Ql %G ,
.Ql %g
and
.Ql \&%V
are defined in ISO 8601: 1988.
.Sh BUGS
There is no conversion specification for the phase of the moon.

@ -17,7 +17,7 @@
#ifdef LIBC_RCS
static const char rcsid[] =
"$Id: strftime.c,v 1.17 1997/02/22 15:03:19 peter Exp $";
"$Id: strftime.c,v 1.18 1997/08/09 15:43:53 joerg Exp $";
#endif
#ifndef lint
@ -234,67 +234,89 @@ label:
pt = _conv((t->tm_wday == 0) ? 7 : t->tm_wday,
"%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.
*/
case 'V': /* ISO 8601 week number */
case 'G': /* ISO 8601 year (four digits) */
case 'g': /* ISO 8601 year (two digits) */
/*
** 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 i;
int year;
int yday;
int wday;
int w;
i = (t->tm_yday + 10 - (t->tm_wday ?
(t->tm_wday - 1) : 6)) / 7;
if (i == 0) {
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 day of the week does
** January 1 fall on?
** What yday (-3 ... 3) does
** the ISO year begin on?
*/
i = t->tm_wday -
(t->tm_yday - 1);
bot = ((yday + 11 - wday) %
DAYSPERWEEK) - 3;
/*
** Fri Jan 1: 53
** Sun Jan 1: 52
** Sat Jan 1: 53 if previous
** year a leap
** year, else 52
** What yday does the NEXT
** ISO year begin on?
*/
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 */
top = bot -
(len % DAYSPERWEEK);
if (top < -3)
top += DAYSPERWEEK;
top += len;
if (yday >= top) {
++year;
w = 1;
break;
}
if (yday >= bot) {
w = 1 + ((yday - bot) /
DAYSPERWEEK);
break;
}
--year;
yday += isleap(year) ?
DAYSPERLYEAR :
DAYSPERNYEAR;
}
pt = _conv(i, "%02d", pt, ptlim);
#ifdef XPG4_1994_04_09
if ((w == 52
&& t->tm_mon == TM_JANUARY)
|| (w == 1
&& t->tm_mon == TM_DECEMBER))
w = 53;
#endif /* defined XPG4_1994_04_09 */
if (*format == 'V')
pt = _conv(w, "%02d",
pt, ptlim);
else if (*format == 'g') {
pt = _conv(year % 100, "%02d",
pt, ptlim);
} else pt = _conv(year, "%04d",
pt, ptlim);
}
continue;
case 'v':