Date: Fri, 21 Nov 2003 13:15:29 -0600 From: Dan Nelson <dnelson@allantgroup.com> To: freebsd-standards@freebsd.org Subject: mktime and tm_isdst Message-ID: <20031121191529.GD2146@dan.emsphone.com>
next in thread | raw e-mail | index | archive | help
--1yeeQ81UyVL57Vl7 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline I've got a question about mktime and FreeBSD's use of the tm_isdst flag. POSIX says: http://www.opengroup.org/onlinepubs/007904975/functions/mktime.html A positive or 0 value for tm_isdst shall cause mktime() to presume initially that Daylight Savings Time, respectively, is or is not in effect for the specified time. "presume initially" I guess is a euphamism for "implementation defined", since it allows the implementation to override the value if it happens to determine the correct value. A defect reported posted for C99 asks the question: http://std.dkuug.dk/JTC1/SC22/WG14/www/docs/dr_280.htm Q3 In a general case, what should we do in case tm_isdst is different from -1? A3 It is implementation defined. One possibility would be to consider any two struct tm values as being exactly one hour apart if all members have the same value except that one struct tm value has tm_isdst=1 and the other has tm_isdst=0 (regardless of the date stored in the struct tm values). FreeBSD seems to ignore the value of tm_isdst except for the duplicate fall-back hour. Unfortunately, every other OS I've tested (Linux, TRU64 5.1b, AIX 5.2, Solaris 9) trusts the user's tz_isdst value if isn't not -1. Would it be a good idea to change our behaviour to match everyone else's, even though it's in "undefined" territory according to the spec? I've attached a test program to show what I'm talking about. It converts three dates using tm_isdst values of 0, -1, and 1, and prints the time_t generated. -- Dan Nelson dnelson@allantgroup.com --1yeeQ81UyVL57Vl7 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="mktimetest.c" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> int main(int argc, char *argv[]) { struct tm tm; time_t t; putenv("TZ=America/Chicago"); printf("Testing 1994-10-29 01:00:00 (DST)\n"); memset(&t, 0, sizeof(t)); tm.tm_year = 94; tm.tm_mon = 9; tm.tm_mday = 29; tm.tm_hour = 1; tm.tm_min = 0; tm.tm_sec = 0; tm.tm_isdst = 0; t = mktime(&tm); printf("isdst=0 -> %d, isdst=%d\n", t, tm.tm_isdst); memset(&t, 0, sizeof(t)); tm.tm_year = 94; tm.tm_mon = 9; tm.tm_mday = 29; tm.tm_hour = 1; tm.tm_min = 0; tm.tm_sec = 0; tm.tm_isdst = -1; t = mktime(&tm); printf("isdst=-1 -> %d, isdst=%d\n", t, tm.tm_isdst); memset(&t, 0, sizeof(t)); tm.tm_year = 94; tm.tm_mon = 9; tm.tm_mday = 29; tm.tm_hour = 1; tm.tm_min = 0; tm.tm_sec = 0; tm.tm_isdst = 1; t = mktime(&tm); printf("isdst=1 -> %d, isdst=%d\n", t, tm.tm_isdst); printf("Testing 1994-10-30 01:00:00 (could be either)\n"); memset(&t, 0, sizeof(t)); tm.tm_year = 94; tm.tm_mon = 9; tm.tm_mday = 30; tm.tm_hour = 1; tm.tm_min = 0; tm.tm_sec = 0; tm.tm_isdst = 0; t = mktime(&tm); printf("isdst=0 -> %d, isdst=%d\n", t, tm.tm_isdst); memset(&t, 0, sizeof(t)); tm.tm_year = 94; tm.tm_mon = 9; tm.tm_mday = 30; tm.tm_hour = 1; tm.tm_min = 0; tm.tm_sec = 0; tm.tm_isdst = -1; t = mktime(&tm); printf("isdst=-1 -> %d, isdst=%d\n", t, tm.tm_isdst); memset(&t, 0, sizeof(t)); tm.tm_year = 94; tm.tm_mon = 9; tm.tm_mday = 30; tm.tm_hour = 1; tm.tm_min = 0; tm.tm_sec = 0; tm.tm_isdst = 1; t = mktime(&tm); printf("isdst=1 -> %d, isdst=%d\n", t, tm.tm_isdst); printf("Testing 1994-11-01 01:00:00 (not DST)\n"); memset(&t, 0, sizeof(t)); tm.tm_year = 94; tm.tm_mon = 10; tm.tm_mday = 01; tm.tm_hour = 1; tm.tm_min = 0; tm.tm_sec = 0; tm.tm_isdst = 0; t = mktime(&tm); printf("isdst=0 -> %d, isdst=%d\n", t, tm.tm_isdst); memset(&t, 0, sizeof(t)); tm.tm_year = 94; tm.tm_mon = 10; tm.tm_mday = 01; tm.tm_hour = 1; tm.tm_min = 0; tm.tm_sec = 0; tm.tm_isdst = -1; t = mktime(&tm); printf("isdst=-1 -> %d, isdst=%d\n", t, tm.tm_isdst); memset(&t, 0, sizeof(t)); tm.tm_year = 94; tm.tm_mon = 10; tm.tm_mday = 01; tm.tm_hour = 1; tm.tm_min = 0; tm.tm_sec = 0; tm.tm_isdst = 1; t = mktime(&tm); printf("isdst=1 -> %d, isdst=%d\n", t, tm.tm_isdst); return 0; } --1yeeQ81UyVL57Vl7--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20031121191529.GD2146>