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:
parent
ab215c6703
commit
b9b51fb731
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':
|
||||
|
Loading…
x
Reference in New Issue
Block a user