From owner-freebsd-standards@FreeBSD.ORG Fri Nov 21 11:15:31 2003 Return-Path: Delivered-To: freebsd-standards@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 1F53A16A4CE for ; Fri, 21 Nov 2003 11:15:31 -0800 (PST) Received: from dan.emsphone.com (dan.emsphone.com [199.67.51.101]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2A4C743FB1 for ; Fri, 21 Nov 2003 11:15:30 -0800 (PST) (envelope-from dan@dan.emsphone.com) Received: (from dan@localhost) by dan.emsphone.com (8.12.9/8.12.9) id hALJFTJo064838 for freebsd-standards@freebsd.org; Fri, 21 Nov 2003 13:15:29 -0600 (CST) (envelope-from dan) Date: Fri, 21 Nov 2003 13:15:29 -0600 From: Dan Nelson To: freebsd-standards@freebsd.org Message-ID: <20031121191529.GD2146@dan.emsphone.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="1yeeQ81UyVL57Vl7" Content-Disposition: inline X-OS: FreeBSD 5.1-CURRENT X-message-flag: Outlook Error User-Agent: Mutt/1.5.5.1i Subject: mktime and tm_isdst X-BeenThere: freebsd-standards@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Standards compliance List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 21 Nov 2003 19:15:31 -0000 --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 #include #include #include 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--