From owner-freebsd-standards@FreeBSD.ORG Sat Aug 6 06:16:19 2005 Return-Path: X-Original-To: standards@freebsd.org 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 9DA4F16A41F for ; Sat, 6 Aug 2005 06:16:19 +0000 (GMT) (envelope-from imp@bsdimp.com) Received: from harmony.bsdimp.com (vc4-2-0-87.dsl.netrack.net [199.45.160.85]) by mx1.FreeBSD.org (Postfix) with ESMTP id 26EE343D48 for ; Sat, 6 Aug 2005 06:16:19 +0000 (GMT) (envelope-from imp@bsdimp.com) Received: from localhost (localhost.village.org [127.0.0.1] (may be forged)) by harmony.bsdimp.com (8.13.3/8.13.3) with ESMTP id j766FHVd061123 for ; Sat, 6 Aug 2005 00:15:17 -0600 (MDT) (envelope-from imp@bsdimp.com) Date: Sat, 06 Aug 2005 00:16:20 -0600 (MDT) Message-Id: <20050806.001620.82098789.imp@bsdimp.com> To: standards@freebsd.org From: "M. Warner Losh" X-Mailer: Mew version 3.3 on Emacs 21.3 / Mule 5.0 (SAKAKI) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-2.0 (harmony.bsdimp.com [127.0.0.1]); Sat, 06 Aug 2005 00:15:17 -0600 (MDT) Cc: Subject: Inconsistancy between mktime and system time accross leapsecond X-BeenThere: freebsd-standards@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Standards compliance List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 06 Aug 2005 06:16:19 -0000 During a leap second on a system controlled by ntp, the last second of the month is replayed. This keeps the system time in the right day (the leap second is considered to be part of the last day of the month, not the first of the next) and has a few other nice properties. If one gets the time of day during the leap second with ntp_gettime, the time state will indicate that a leap second is in progress and that the TAI offset is now one larger than before. If we look at the TAI offset plus the system time, we get a conversion from the UTC second that time_t represents to the TAI time. mktime, however, when fed a leap second says that it is the first second of the first day of the month (which is the second that gets repeated). posix is silent on what, exactly, to do with leap seconds. It gives a formula that seems to support mktime's return value. However, since leap seconds are undefined in posix's time_t epoch, a case can be made for other values. In addition, there's a one second jump if one tries to compute TAI time from UTC time_t time for the leap second. These flaws, while trivial to many programs, matter to some folks. I'd like to resolve this ambigutiy. Since ntp isn't going to change how it handles leap seconds, and since I believe that to be the right way to deal with leap seconds since it preserves the right day of week and doesn't kick of jobs too early, etc, I'd like to change mktime's behavior to match system time's during the leap second. Comments on the following patch? Warner Index: localtime.c =================================================================== RCS file: /cache/ncvs/src/lib/libc/stdtime/localtime.c,v retrieving revision 1.40 diff -u -r1.40 localtime.c --- localtime.c 24 Aug 2004 00:15:37 -0000 1.40 +++ localtime.c 5 Aug 2005 22:57:21 -0000 @@ -1506,7 +1506,20 @@ saved_seconds = yourtm.tm_sec; yourtm.tm_sec = SECSPERMIN - 1; } else { - saved_seconds = yourtm.tm_sec; + /* + ** Posix time_t is specified such that leap seconds + ** are swizzled into the time. As such, the last + ** second of the day is repeated. Without this adjustment, + ** we incorrectly repeat the first second of the following + ** day. To be pedantically correct, we should look up to + ** see if this is really a leap second or not. + */ + if (yourtm.tm_hour == HOURSPERDAY - 1 && + yourtm.tm_min == MINSPERHOUR - 1 && + yourtm.tm_sec == SECSPERMIN) + saved_seconds = SECSPERMIN - 1; + else + saved_seconds = yourtm.tm_sec; yourtm.tm_sec = 0; } /*