diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 1998-03-15 06:49:02 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 1998-03-15 06:49:02 +0000 |
commit | da01281deeb457fb1c76ea91a5e32e0f89b768e1 (patch) | |
tree | 17c6f5c30bac3e4c3c9c1d8d14a03e2ae2773a96 | |
parent | e42d3d5a02080909c4be95e281bcf76ae2987fae (diff) |
Fix %m, %I, %S, %y, %C, and %j conversions. Fixes by nakayosh@kcn.or.jp
and myself. Some bugs noted by woods@most.weird.com.
-rw-r--r-- | lib/libc/time/strptime.3 | 53 | ||||
-rw-r--r-- | lib/libc/time/strptime.c | 31 |
2 files changed, 48 insertions, 36 deletions
diff --git a/lib/libc/time/strptime.3 b/lib/libc/time/strptime.3 index e8b0a0989f4..4e4e80c20f7 100644 --- a/lib/libc/time/strptime.3 +++ b/lib/libc/time/strptime.3 @@ -1,4 +1,4 @@ -.\" $NetBSD: strptime.3,v 1.4 1998/01/20 21:10:08 mycroft Exp $ +.\" $OpenBSD: strptime.3,v 1.2 1998/03/15 06:49:00 millert Exp $ .\" .\" Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -33,7 +33,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd January 20, 1998 +.Dd March 14, 1998 .Os .Dt STRPTIME 3 .Sh NAME @@ -55,15 +55,15 @@ using the format specified by .Pp The .Fa format -string consists of zero or more conversion specifications and -ordinary characters. All ordinary characters are copied directly into -the buffer. A conversion specification consists of a percent sign `%' -followed by one or two conversion characters which specify the replacement -required. There must be white-space or other non-alphanumeric characters -between any two conversion specifications. +string consists of zero or more conversion specifications and ordinary +characters. All ordinary characters are copied directly into the +buffer. A conversion specification consists of a percent sign `%' +followed by one or two conversion characters which specify the +replacement required. There must be white-space or other +non-alphanumeric characters between any two conversion specifications. .Pp The LC_TIME category defines the locale values for the conversion -specifications. The following conversion specifications are supported: +specifications. The following conversion specifications are supported: .Bl -tag -width "xxxx" .It Cm \&%a the day of week, using the locale's weekday names; @@ -80,11 +80,12 @@ the same as .It Cm \&%c the date and time, using the locale's date and time format. .It Cm \&%C -the century number [0,99]; -leading zeros are permitted but not required. +the century number [0,99]; leading zeros are permitted but not required. +Note that the converted value is added to the current value of the +``tm_year'' field (in order that the "\&%y" conversion be useful). .It Cm \&%d the day of month [1,31]; -leading zeros are permitted but required. +leading zeros are permitted but not required. .It Cm \&%D the date as %m/%d/%y. .It Cm \&%e @@ -119,7 +120,7 @@ any white-space .It Cm \&%p the locale's equivalent of a.m. or p.m.. .It Cm \&%r -the time (12-hour clock) with %p, using the locale's time format. +the time as %I:%M:%S %p. .It Cm \&%R the time as %H:%M. .It Cm \&%S @@ -147,12 +148,15 @@ the date, using the locale's date format. .It Cm \&%X the time, using the locale's time format. .It Cm \&%y -the year within the 20th century [69,99] or the 21st century [0,68]; -leading zeros are permitted but not required. +the year within the current century. When a century is not otherwise +specified, values in the range 69-99 refer to years in the twentieth +century (1969 to 1999 inclusive); values in the range 00-68 refer +to years in the twenty-first century (2000 to 2068 inclusive). +Leading zeros are permitted but not required. .It Cm \&%Y -the year, including the century (i.e., 1996). +the year, including the century (i.e., 1998). .It Cm \&%% -A `%' is written. No argument is converted. +A `%' is written. No argument is converted. .El .Ss Modified conversion specifications For compatibility, certain conversion specifications can be modified @@ -160,20 +164,21 @@ by the .Cm E and .Cm O -modifier characters to indicate that an alternative format or specification -should be used rather than the one normally used by the unmodified -conversion specification. As there are currently neither alternative formats -nor specifications supported by the system, the behavior will be as if the -unmodified conversion specification were used. +modifier characters to indicate that an alternative format or +specification should be used rather than the one normally used by the +unmodified conversion specification. As there are currently neither +alternative formats nor specifications supported by the system, the +behavior will be as if the unmodified conversion specification were +used. .Sh RETURN VALUES If successful, the .Nm function returns a pointer to the character following the last character -parsed. Otherwise, a null pointer is returned. +parsed. Otherwise, a null pointer is returned. .Sh SEE ALSO .Xr strftime 3 .Sh STANDARDS The .Fn strptime function conforms to -.St -xpg4 . +.St -xpg4.2 . diff --git a/lib/libc/time/strptime.c b/lib/libc/time/strptime.c index 82aa93c162a..c1f6cbbf5f5 100644 --- a/lib/libc/time/strptime.c +++ b/lib/libc/time/strptime.c @@ -36,7 +36,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: strptime.c,v 1.1 1998/02/04 22:22:43 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: strptime.c,v 1.2 1998/03/15 06:49:01 millert Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/localedef.h> @@ -68,6 +68,7 @@ strptime(buf, fmt, tm) char c; const char *bp; int alt_format, i, len; + int century = TM_YEAR_BASE; bp = buf; @@ -131,9 +132,9 @@ literal: return (0); break; - case 'r': /* The time in 12-hour clock representation. */ + case 'r': /* The time as "%I:%M:%S %p". */ _LEGAL_ALT(0); - if (!(bp = strptime(bp, _ctloc(t_fmt_ampm), tm))) + if (!(bp = strptime(bp, "%I:%M:%S %p", tm))) return (0); break; @@ -210,7 +211,7 @@ literal: if (!(_conv_num(&bp, &i, 0, 99))) return (0); - tm->tm_year = i * 100; + century = i * 100; break; case 'd': /* The day of month. */ @@ -234,7 +235,7 @@ literal: /* FALLTHROUGH */ case 'I': _LEGAL_ALT(_ALT_O); - if (!(_conv_num(&bp, &tm->tm_hour, 0, 11))) + if (!(_conv_num(&bp, &tm->tm_hour, 1, 12))) return (0); break; @@ -242,6 +243,7 @@ literal: _LEGAL_ALT(0); if (!(_conv_num(&bp, &tm->tm_yday, 1, 366))) return (0); + tm->tm_yday--; break; case 'M': /* The minute. */ @@ -254,6 +256,7 @@ literal: _LEGAL_ALT(_ALT_O); if (!(_conv_num(&bp, &tm->tm_mon, 1, 12))) return (0); + tm->tm_mon--; break; case 'p': /* The locale's equivalent of AM/PM. */ @@ -284,7 +287,7 @@ literal: case 'S': /* The seconds. */ _LEGAL_ALT(_ALT_O); - if (!(_conv_num(&bp, &tm->tm_sec, 1, 61))) + if (!(_conv_num(&bp, &tm->tm_sec, 0, 61))) return (0); break; @@ -315,15 +318,19 @@ literal: tm->tm_year = i - TM_YEAR_BASE; break; - case 'y': /* The year within 100 years of the epoch. */ + case 'y': /* The year within the century (2 digits). */ _LEGAL_ALT(_ALT_E | _ALT_O); if (!(_conv_num(&bp, &i, 0, 99))) return (0); - if (i <= 68) - tm->tm_year = i + 2000 - TM_YEAR_BASE; - else - tm->tm_year = i + 1900 - TM_YEAR_BASE; + if (century == TM_YEAR_BASE) { + if (i <= 68) + tm->tm_year = i + 2000 - TM_YEAR_BASE; + else + tm->tm_year = i + 1900 - TM_YEAR_BASE; + } else { + tm->tm_year = i + century - TM_YEAR_BASE; + } break; /* @@ -364,7 +371,7 @@ _conv_num(buf, dest, llim, ulim) *dest += *(*buf)++ - '0'; } while ((*dest * 10 <= ulim) && **buf >= '0' && **buf <= '9'); - if (*dest < llim || *dest > ulim) + if (*dest < llim || *dest > ulim || isdigit(**buf)) return (0); return (1); |