This is the mail archive of the
libc-hacker@sourceware.cygnus.com
mailing list for the glibc project.
getdate && Y2K
- To: libc-alpha@cygnus.com
- Subject: getdate && Y2K
- From: Andreas Jaeger <aj@arthur.rhein-neckar.de>
- Date: Fri, 18 Dec 1998 10:08:23 +0100 (CET)
Hi,
I've downloaded some Y2K test programs from:
ftp://ftp.rdg.opengroup.org/pub/unsupported/stdtools/y2k/
and got a segmentation fault using the getdate.c program :-(.
Could somebody check if either the testprogram (appended below) or the
getdate implementation in glibc2.1 is broken and fix it?
Thanks,
Andreas
/*
* getdate() %y checker
*
* Note that UNIX systems are required only to be able to
* represent dates up until between Jan 1 1970 and Jan 1 2038,
* some systems may be able to handle a wider range but its
* not required.
*
* Symptons of the non handling of the range is a core dump,
* if this occurs see below -re TOG_END
*
* This test requires a file called datemsk to be in the current
* directory with the contents "%d/%m/%y"
*
* Author: Andrew Josey, (ajosey@xopen.org)
* Based on the idea seen for a test for strptime on comp.unix.aix
* reworked to allow for the Jan 1 1970 - Jan 1 2038 limits on
* some systems.
*/
#ifndef lint
static char *_version = "@(#)getdate_win.c 1.1 - 98/06/08";
#endif
/*
* Determine window for the getdate() function.
*/
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#ifdef sun
#include <tzfile.h>
#else
#define TM_YEAR_BASE 1900
#endif
main()
{
int i;
struct tm tm_struct, *tm_ptr;
char buf[9];
int years[100];
char s[20];
tm_ptr = &tm_struct;
sprintf (s, "DATEMSK=./datemsk");
putenv(s);
/* some systems may handle 0 to 100, if so change the 38
* to 100 and the next code block will disappear
*/
#define TOG_START 0
#define TOG_END 100
/*#define TOG_END 38 */ /* comment in if core dumps occur */
for (i = TOG_START ; i < TOG_END; i++) {
sprintf(buf, "01/01/%02d", i);
/* printf("i=%d,template=%s\n",i, buf);*/
tm_ptr = getdate (buf);
years[i] = tm_ptr->tm_year + TM_YEAR_BASE;
/* printf("YEAR=%d\n", years[i]);*/
}
#if (TOG_END - 38 == 0)
for (i = 69; i < 100; i++) {
sprintf(buf, "01/01/%02d", i);
/* printf("i=%d,template=%s\n",i, buf);*/
tm_ptr = getdate (buf);
years[i] = tm_ptr->tm_year + TM_YEAR_BASE;
/* printf("YEAR=%d\n", years[i]);*/
}
#endif
printf("getdate(3C) window: %04d-", years[0]);
for (i = 1; i < TOG_END; i++) {
if (years[i-1] / 100 != years[i] / 100)
printf("%04d %04d-", years[i-1], years[i]);
}
printf("%04d ", years[TOG_END-1]);
#if (TOG_END - 38 == 0)
printf("%04d-", years[69]);
for (i = 70; i < 100; i++) {
if (years[i-1] / 100 != years[i] / 100)
printf("%04d %04d-", years[i-1], years[i]);
}
printf("%04d\n", years[99]);
#endif
exit(0);
return (0); /* quiet lint gripes */
}
%m/%d/%y
Programs to interrogate the systems handling of two digit dates
---------------------------------------------------------------
Module: getdate.c
Description:
struct tm *getdate(const char *string);
The X/Open CAE Specification, System Interfaces and Headers Issue 4,
Version 2 (September 1994), in the entry for getdate() on page 231,
states the following with respect to the format code %y:
"%y year within century (00-99)"
Suppose there is a line of the form "%m/%d/%y" in the template file,
and a call is made:
struct tm * p_tm;
p_tm = getdate( "11/22/02" );
It is not specified what would be represented in the struct tm for the
century. This could be interpreted as either 11/22/1902 or 11/22/2002
since the implementation does not know which "century" this is to refer
to.
This test module has a DATEMSK of "%d/%m/%y" and will call
getdate() with a date of "01/01/%2d" where %2d will increment from
00 to 99. The test module will then print out the windows that the
getdate() function handles, for example
getdate(3C) window: 2000-2068 1969-1999
Note that the Single UNIX Specification only requires that systems
be able to represent the time between Jan 1 1970 and Jan 1 2038,
thus some systems will have a window of 2000-2038 rather than 2000-2068.
To enable the test to work on those systems edit the TOG_END
value from 99 to 38.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Module: strptime.c
Description:
char *strptime(const char *buf, const char *format, struct tm *tm);
The X/Open CAE Specification, System Interfaces and Headers Issue 4,
Version 2 (September 1994), in the entry for strptime() on page 615,
states the following with respect to the format code %y:
"%y is the year within century [00,99]; leading zeros are
permitted but not required"
Suppose that the following call is made:
struct tm thetime;
strptime( "11/22/02", "%m/%d/%y", &thetime );
It is not specified what would be represented in the struct tm for the
century. This could be interpreted as either 11/22/1902 or 11/22/2002
since the implementation does not know which "century" this is to refer
to.
The test module takes a similar strategy to getdate.c.
Typical outlook looks like:
strptime(3C) window: 2000-2068 1969-1999
or
strptime(3C) window: 2000-2038 1969-1999
--
Andreas Jaeger aj@arthur.rhein-neckar.de jaeger@informatik.uni-kl.de
for pgp-key finger ajaeger@aixd1.rhrk.uni-kl.de