bug-gnu-utils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

gawk-3.0.95 fixes for Y2k and other date and time problems


From: Paul Eggert
Subject: gawk-3.0.95 fixes for Y2k and other date and time problems
Date: Mon, 26 Feb 2001 13:27:07 -0800 (PST)

Here are fixes for some Y2k and other date-and-time problems in gawk
3.0.95.

The most important fix is that for mktime.  mktime lets you do simple
time arithmetic (e.g. to find out the time stamp one hour before the
start of a day), but gawk's do_mktime lets you do only very limited
instances of this (e.g. it lets you find out the time stamp for one
day after September 30, but not for one day after October 31).

This patch removes these unnecessary restrictions, and lets the user
get the full functionality of the underlying mktime by letting the
user specify tm_isdst.  It also checks for a couple of overflows that
gawk 3.0.95 misses.

2001-02-26  Paul Eggert  <address@hidden>

        * COPYING: Incorporate latest version from FSF, which fixes a Y2k bug.

        * builtin.c (do_mktime): Allow the user to specify the
        tm_isdst member as an optional trailing integer, and to
        specify "out-of-range" members.  Check for overflow when
        subtracting 1 from month or 1900 from year.  Allow years just
        past INT_MAX, as they work on some hosts when INT_MAX - 1900
        is representable as an int.

        * doc/gawk.1, doc/gawk.texi: Document the above changes.
        Also, document that the origin-zero Gregorian calendar is used.
        Fix confusing wording about "midnight" by replacing it with 00:00
        ("midnight" is also 24:00, the end of the day).
        Mention the typical range for time stamps.
        Do not assume that years are nonnegative and are less than 10,000.
        Suggest TZ=UTC0 instead of TZ=GMT0, as that's how recent versions
        of GNU date behave.
        GMT is not always the time of day in Greenwich these days.
        Fix typos: "Emporer/Era", "1980's", "1970's".

diff -ru gawk-3.0.95/COPYING gawk-3.0.95-fix1/COPYING
--- gawk-3.0.95/COPYING Wed Jun  4 16:37:12 1997
+++ gawk-3.0.95-fix1/COPYING    Wed Feb 10 05:47:30 1999
@@ -2,7 +2,7 @@
                       Version 2, June 1991
 
  Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  Everyone is permitted to copy and distribute verbatim copies
  of this license document, but changing it is not allowed.
 
@@ -291,7 +291,7 @@
 the "copyright" line and a pointer to where the full notice is found.
 
     <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) 19yy  <name of author>
+    Copyright (C) <year>  <name of author>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -313,7 +313,7 @@
 If the program is interactive, make it output a short notice like this
 when it starts in an interactive mode:
 
-    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision version 69, Copyright (C) year  name of author
     Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
     This is free software, and you are welcome to redistribute it
     under certain conditions; type `show c' for details.
diff -ru gawk-3.0.95/builtin.c gawk-3.0.95-fix1/builtin.c
--- gawk-3.0.95/builtin.c       Wed Feb 21 07:43:00 2001
+++ gawk-3.0.95-fix1/builtin.c  Mon Feb 26 20:53:29 2001
@@ -1210,7 +1210,9 @@
 {
        NODE *t1;
        struct tm then;
-       int year, month, day, hour, minute, second, count;
+       long year;
+       int month, day, hour, minute, second, count;
+       int dst = -1; /* default is unknown */
        time_t then_stamp;
        char save;
 
@@ -1222,18 +1224,17 @@
        save = t1->stptr[t1->stlen];
        t1->stptr[t1->stlen] = '\0';
 
-       count = sscanf(t1->stptr, "%d %d %d %d %d %d", & year, & month, & day,
-                       & hour, & minute, & second);
+       count = sscanf(t1->stptr, "%ld %d %d %d %d %d %d",
+                       & year, & month, & day,
+                       & hour, & minute, & second,
+                       & dst);
 
        t1->stptr[t1->stlen] = save;
        free_temp(t1);
 
-       if (count != 6)
-               return tmp_number((AWKNUM) -1);
-
-       if (year < 1900 || month < 1 || month > 12 || day < 1 || day > 31
-           || hour < 0 || hour > 23 || minute < 0 || minute > 59
-           || second < 0 || second > 60 /* one leap second allowed */)
+       if (count < 6
+           || month < month - 1
+           || year < year - 1900 || year - 1900 != (int) (year - 1900))
                return tmp_number((AWKNUM) -1);
 
        memset(& then, '\0', sizeof(then));
@@ -1243,7 +1244,7 @@
        then.tm_mday = day;
        then.tm_mon = month - 1;
        then.tm_year = year - 1900;
-       then.tm_isdst = -1;     /* unknown */
+       then.tm_isdst = dst;
 
        then_stamp = mktime(& then);
        return tmp_number((AWKNUM) then_stamp);
diff -ru gawk-3.0.95/doc/gawk.1 gawk-3.0.95-fix1/doc/gawk.1
--- gawk-3.0.95/doc/gawk.1      Sun Jan 28 15:43:08 2001
+++ gawk-3.0.95-fix1/doc/gawk.1 Mon Feb 26 20:59:14 2001
@@ -2466,19 +2466,31 @@
 The
 .I datespec
 is a string of the form
-.IR "YYYY MM DD HH MM SS" .
-The contents of the string are six numbers representing respectively
-the year with century,
+.IR "YYYY MM DD HH MM SS[ DST]" .
+The contents of the string are six or seven numbers representing respectively
+the full year including century,
 the month from 1 to 12,
 the day of the month from 1 to 31,
 the hour of the day from 0 to 23,
 the minute from 0 to 59,
-and the second from 0 to 60.
+and the second from 0 to 60,
+and an optional daylight saving flag.
+The values of these numbers need not be within the ranges specified;
+for example, an hour of \-1 means 1 hour before midnight.
+The origin-zero Gregorian calendar is assumed,
+with year 0 preceding year 1 and year \-1 preceding year 0.
 The time is assumed to be in the local timezone.
+If the daylight saving flag is positive,
+the time is assumed to be daylight saving time;
+if zero, the time is assumed to be standard time;
+and if negative (the default),
+.B mktime
+attempts to determine whether daylight saving time is in effect
+for the specified time.
 If
 .I datespec
-does not contain enough elements, or any of them are out of the above
-ranges,
+does not contain enough elements or if the resulting time
+is out of range,
 .B mktime
 returns \-1.
 .TP
@@ -2514,7 +2526,7 @@
 .TP
 .B systime()
 returns the current time of day as the number of seconds since the Epoch
-(Midnight UTC, January 1, 1970 on \*(PX systems).
+(1970-01-01 00:00:00 UTC on \*(PX systems).
 .SS Bit Manipulations Functions
 Starting with version 3.1 of
 .IR gawk ,
diff -ru gawk-3.0.95/doc/gawk.texi gawk-3.0.95-fix1/doc/gawk.texi
--- gawk-3.0.95/doc/gawk.texi   Sun Feb 25 11:46:35 2001
+++ gawk-3.0.95-fix1/doc/gawk.texi      Mon Feb 26 21:03:34 2001
@@ -12147,8 +12147,13 @@
 in the form returned by the @code{time} system call, which is the
 number of seconds since a particular epoch.  On POSIX-compliant systems,
 it is the number of seconds since
-Midnight, January 1, 1970, address@hidden@xref{Glossary},
+1970-01-01 00:00:00 UTC, not counting leap address@hidden@xref{Glossary},
 especially the entries for ``Epoch'' and ``UTC.''}
+All known POSIX-compliant systems support time stamps from 0 through
address@hidden - 1}, which is sufficient to represent times through
+2038-01-19 03:14:07 UTC.  Many systems support a wider range of time
+stamps, including negative time stamps that represent times before the
+epoch.
 
 In order to make it easier to process such log files and to produce
 useful reports, @command{gawk} provides the following functions for working 
with time
@@ -12163,7 +12168,8 @@
 @cindex @code{systime} built-in function
 This function returns the current time as the number of seconds since
 the system epoch.  On POSIX systems, this is the number of seconds
-since Midnight, January 1, 1970, UTC.  It may be a different number on
+since 1970-01-01 00:00:00 UTC, not counting leap seconds.
+It may be a different number on
 other systems.
 
 @item mktime(@var{datespec})
@@ -12172,16 +12178,25 @@
 returned by @code{systime}.  It is similar to the function of the
 same name in ISO C.  The argument, @var{datespec}, is a string
 of the form
address@hidden@code{"@var{YYYY} @var{MM} @var{DD} @var{HH} @var{MM} @var{SS}"}}.
-The contents of the string are six numbers representing respectively
-the year with century, the month from 1 to 12, the day of the month
address@hidden@code{"@var{YYYY} @var{MM} @var{DD} @var{HH} @var{MM} @var{SS}[ 
@var{DST}]"}}.
+The contents of the string are six or seven numbers representing respectively
+the full year including century, the month from 1 to 12, the day of the month
 from 1 to 31, the hour of the day from 0 to 23, the minute from 0 to
-59, and the second from 0 to address@hidden there are
+59, the second from 0 to 60,@footnote{Occasionally there are
 minutes in a year with a leap second, which is why the
 seconds can go up to 60.}
+and an optional daylight saving flag.
+The values of these numbers need not be within the ranges specified;
+for example, an hour of @minus{}1 means 1 hour before midnight.
+The origin-zero Gregorian calendar is assumed, with year 0 preceding
+year 1 and year @minus{}1 preceding year 0.
 The time is assumed to be in the local timezone.
-If @var{datespec} does not contain enough elements or if any of them are
-out of the above ranges, @code{mktime} returns @minus{}1.
+If the daylight saving flag is positive, the time is assumed to be
+daylight saving time; if zero, the time is assumed to be standard
+time; and if negative (the default), @code{mktime} attempts to determine
+whether daylight saving time is in effect for the specified time.
+If @var{datespec} does not contain enough elements or if the resulting time
+is out of range, @code{mktime} returns @minus{}1.
 
 @item strftime(@address@hidden @r{[}, @address@hidden)
 @cindex @code{strftime} built-in function
@@ -12242,7 +12257,8 @@
 (This is @samp{%A %B %d %T %Y} in the @code{"C"} locale; see below.)
 
 @item %C
-The century as a number between 00 and 99.
+The century.  This is the year divided by 100 and truncated to the next
+lower integer.
 
 @item %d
 The day of the month as a decimal number (01--31).
@@ -12258,7 +12274,7 @@
 This is the ISO 8601 date format.
 
 @item %g
-The year without century of the ISO week number, as a decimal number (00--99).
+The year modulo 100 of the ISO week number, as a decimal number (00--99).
 
 For example, January 1, 1993, is in week 53 of 1992. Thus, the year
 of its ISO week number is 1992, even though its year is 1993.
@@ -12266,7 +12282,7 @@
 of its ISO week number is 1974, even though its year is 1973.
 
 @item %G
-The year with century of the ISO week number, as a decimal number.
+The full year of the ISO week number, as a decimal number.
 
 @item %h
 Equivalent to @samp{%b}, above.
@@ -12342,10 +12358,10 @@
 (This is @samp{%T} in the @code{"C"} locale.)
 
 @item %y
-The year without century as a decimal number (00--99).
+The year modulo 100 as a decimal number (00--99).
 
 @item %Y
-The year with century as a decimal number (e.g., 1995).
+The full year as a decimal number (e.g., 1995).
 
 @cindex RFC 822
 @cindex RFC 1036
@@ -12407,11 +12423,11 @@
 Single digit numbers are padded with a space.
 
 @item %N
-The ``Emporer/Era'' name.
+The ``Emperor/Era'' name.
 Equivalent to @code{%C}.
 
 @item %o
-The ``Emporer/Era''year.
+The ``Emperor/Era''year.
 Equivalent to @code{%y}.
 
 @item %s
@@ -12448,7 +12464,7 @@
 # date --- approximate the P1003.2 'date' command
 
 case $1 in
--u)  TZ=GMT0     # use UTC
+-u)  TZ=UTC0     # use UTC
      export TZ
      shift ;;
 esac
@@ -16384,8 +16400,8 @@
 #    time["month"]        -- month of year (1 - 12)
 #    time["monthname"]    -- name of the month
 #    time["shortmonth"]   -- short name of the month
-#    time["year"]         -- year within century (0 - 99)
-#    time["fullyear"]     -- year with century (19xx or 20xx)
+#    time["year"]         -- year modulo 100 (0 - 99)
+#    time["fullyear"]     -- full year
 #    time["weekday"]      -- day of week (Sunday = 0)
 #    time["altweekday"]   -- day of week (Monday = 0)
 #    time["dayname"]      -- name of weekday
@@ -24868,7 +24884,7 @@
 the authors of the first book on C.  (Dennis Ritchie created the language,
 and Brian Kernighan was one of the creators of @command{awk}.)
 
-In the mid-1980's, effort was started to produce an international standard
+In the mid-1980s, effort was started to produce an international standard
 for C.  This work culminated in 1989, with the production of the ANSI
 standard for C.  This standard became an ISO standard in 1990.
 Where it makes sense, POSIX @command{awk} is compatible with 1990 ISO C.
@@ -25285,7 +25301,7 @@
 with library functions available for converting these values into
 standard date and time formats.
 
-The epoch on Unix and POSIX systems is Midnight, January 1, 1970, UTC.
+The epoch on Unix and POSIX systems is 1970-01-01 00:00:00 UTC.
 See also ``GMT'' and ``UTC.''
 
 @item Escape Sequences
@@ -25660,7 +25676,7 @@
 @cindex FreeBSD
 @cindex OpenBSD
 @item Unix
-A computer operating system originally developed in the early 1970's at
+A computer operating system originally developed in the early 1970s at
 AT&T Bell Laboratories.  It initially became popular in universities around
 the world and later moved into commercial evnironments as a software
 development system and network server system. There are many commercial
@@ -25669,7 +25685,7 @@
 
 @item UTC
 The accepted abbreviation for ``Universal Coordinated Time.''
-This is the time of day in Greenwich, England, which is used as a
+This is standard time in Greenwich, England, which is used as a
 reference time for day and date calculations.
 See also ``Epoch'' and ``GMT.''
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]