Bug 43592 - mktime(3) rejects dates at the start of daylight savings time
Summary: mktime(3) rejects dates at the start of daylight savings time
Status: Closed Not A Bug
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: 4.6-STABLE
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-bugs (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2002-10-02 18:00 UTC by Ben Burke
Modified: 2014-12-17 12:32 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ben Burke 2002-10-02 18:00:09 UTC
      FreeBSD's mktime behavior for the "missing" hour at the start of daylight savings time is to return -1. Other OSes that I use and have tested compensate for this gap. The short program below shows the leap from 1 AM to -1 on FreeBSD, and from 1 AM to 3 AM on Linux or OSX.

How-To-Repeat:       Compile the short C++ program below and run.

#include <iostream.h>
#include <time.h>

int main() {
struct tm date1;
date1.tm_sec = 0; /* seconds (0 - 60) */
date1.tm_min = 0; /* minutes (0 - 59) */
date1.tm_hour = 2; /* hours (0 - 23) */
date1.tm_mday = 4; /* day of month (1 - 31) */
date1.tm_mon = 3; /* month of year (0 - 11) */
date1.tm_year = 104; /* year - 1900 */

cout << mktime(&date1) << "\n";

/* An hour later */
struct tm date2;
date2.tm_sec = 0; /* seconds (0 - 60) */
date2.tm_min = 0; /* minutes (0 - 59) */
date2.tm_hour = 3; /* hours (0 - 23) */
date2.tm_mday = 4; /* day of month (1 - 31) */
date2.tm_mon = 3; /* month of year (0 - 11) */
date2.tm_year = 104; /* year - 1900 */
date1.tm_isdst = -1; /* year - 1900 */

cout << mktime(&date2) << "\n";
}
Comment 1 Ben Burke 2002-10-02 18:11:11 UTC
On second though this pr is a duplicate of bin/40278. My bad.
Comment 2 wollman 2002-10-02 20:11:07 UTC
<<On Wed, 2 Oct 2002 09:50:26 -0700 (PDT), Ben Burke <ben@dubuque365.com> said:

> int main() {
> struct tm date1;
> date1.tm_sec = 0; /* seconds (0 - 60) */
> date1.tm_min = 0; /* minutes (0 - 59) */
> date1.tm_hour = 2; /* hours (0 - 23) */
> date1.tm_mday = 4; /* day of month (1 - 31) */
> date1.tm_mon = 3; /* month of year (0 - 11) */
> date1.tm_year = 104; /* year - 1900 */

> cout << mktime(&date1) << "\n";

It might help if you initialized date1::tm_isdst before it is used.

> /* An hour later */
> struct tm date2;
> date2.tm_sec = 0; /* seconds (0 - 60) */
> date2.tm_min = 0; /* minutes (0 - 59) */
> date2.tm_hour = 3; /* hours (0 - 23) */
> date2.tm_mday = 4; /* day of month (1 - 31) */
> date2.tm_mon = 3; /* month of year (0 - 11) */
> date2.tm_year = 104; /* year - 1900 */
> date1.tm_isdst = -1; /* year - 1900 */

> cout << mktime(&date2) << "\n";

Likewise date2::tm_isdst.

In order to debug this problem (assuming that it is not simply the
result of this error in your code), we will need to know the precise
name of the timezone under which you are running the program.

-GAWollman
Comment 3 wollman 2002-10-03 19:37:13 UTC
For audit trail...

------- start of forwarded message (RFC 934 encapsulation) -------
Return-Path: <ben@dubuque365.com>
Received: from mintaka.lcs.mit.edu (mintaka.lcs.mit.edu [18.26.0.36])
	by khavrinen.lcs.mit.edu (8.12.3/8.12.5) with ESMTP id g935GFgQ004390
	(version=TLSv1/SSLv3 cipher=EDH-RSA-DES-CBC3-SHA bits=168 verify=OK)
	for <wollman@khavrinen.lcs.mit.edu>; Thu, 3 Oct 2002 01:16:15 -0400 (EDT)
	(envelope-from ben@dubuque365.com)
Received: from dubuque365.com (dubuque365.com [66.111.75.26])
	by mintaka.lcs.mit.edu (8.12.5/8.12.5) with ESMTP id g935GCYg000252
	for <wollman@lcs.mit.edu>; Thu, 3 Oct 2002 01:16:13 -0400 (EDT)
	(envelope-from ben@dubuque365.com)
Received: from watchtower.office.parksmediagroup.com (12-219-104-246.client.mchsi.com [12.219.104.246])
	by dubuque365.com (8.11.0/8.11.0) with ESMTP id g935GBP64670
	for <wollman@lcs.mit.edu>; Thu, 3 Oct 2002 00:16:11 -0500 (CDT)
	(envelope-from ben@dubuque365.com)
In-Reply-To: <200210021911.g92JB7cM000635@khavrinen.lcs.mit.edu>
References: <200210021650.g92GoQtZ047931@www.freebsd.org> 
	<200210021911.g92JB7cM000635@khavrinen.lcs.mit.edu>
Content-Type: multipart/mixed; boundary="=-2zhfcTpgZzOLhkYIAqaQ"
X-Mailer: Ximian Evolution 1.0.8 
Message-Id: <1033622171.74394.13.camel@watchtower.office.parksmediagroup.com>
Mime-Version: 1.0
From: Ben Burke <ben@dubuque365.com>
To: Garrett Wollman <wollman@lcs.mit.edu>
Subject: Re: bin/43592: mktime rejects dates at the start of daylight
	savings time
Date: 03 Oct 2002 00:16:10 -0500


- --=-2zhfcTpgZzOLhkYIAqaQ
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

My apologies, I was playing with the code before I sent it and I must
have sent the wrong one. Attached is a corrected (and slightly expanded)
version... along with it's output from my machine. I'm very new to
C/C++, so there there could be other mistakes. I originally discovered
the issue when trying to use PHP's mktime function on a FreeBSD box.

I compiled with:
g++ -Wall -o mktime_test mktime_test.cc

Thanks,

Ben

- --=-2zhfcTpgZzOLhkYIAqaQ
Content-Disposition: attachment; filename=test_output.txt
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; name=test_output.txt; charset=ISO-8859-1

1081062000 - CST
- -1 - z=B8P=D5=01
1081065600 - CDT

- --=-2zhfcTpgZzOLhkYIAqaQ
Content-Disposition: attachment; filename=mktime_test.cc
Content-Transfer-Encoding: quoted-printable
Content-Type: text/x-c; name=mktime_test.cc; charset=ISO-8859-1

#include <iostream.h>
#include <time.h>

int main() {

/* Before DST */
struct tm date1;
date1.tm_sec =3D 0;    /* seconds (0 - 60) */
date1.tm_min =3D 0;    /* minutes (0 - 59) */
date1.tm_hour =3D 1;   /* hours (0 - 23) */
date1.tm_mday =3D 4;   /* day of month (1 - 31) */
date1.tm_mon =3D 3;    /* month of year (0 - 11) */
date1.tm_year =3D 104; /* year - 1900 */
date1.tm_isdst =3D -1; /* is summer time in effect? */

cout << mktime(&date1) << " - ";
cout << date1.tm_zone << "\n";


/* Starting DST */
struct tm date2;
date2.tm_sec =3D 0;
date2.tm_min =3D 0;
date2.tm_hour =3D 2;
date2.tm_mday =3D 4;
date2.tm_mon =3D 3;
date2.tm_year =3D 104;
date2.tm_isdst =3D -1;

cout << mktime(&date2) << " - ";
cout << date2.tm_zone << "\n";


/* During DST */
struct tm date3;
date3.tm_sec =3D 0;
date3.tm_min =3D 0;
date3.tm_hour =3D 3;
date3.tm_mday =3D 4;
date3.tm_mon =3D 3;
date3.tm_year =3D 104;
date3.tm_isdst =3D -1;

cout << mktime(&date3) << " - ";
cout << date3.tm_zone << "\n";


}

- --=-2zhfcTpgZzOLhkYIAqaQ--
------- end -------
Comment 4 Andre Albsmeier 2002-10-04 12:18:37 UTC
Is this similar to PR# 15520 ?

http://www.freebsd.org/cgi/query-pr.cgi?pr=bin/15520
Comment 5 Ben Burke 2002-10-04 13:36:58 UTC
Andre-

I though I queried for that... but this is the second duplicate that I
missed. Sorry about that.

I read the conclusions in 15520 and I strongly disagree with those
conclusions. Please consider that posix doesn't limit the values to the
ranges for the fields... so for instance you can ask for the 47th day of
a month and you don't get an error, you get what would be the 47th day
of that month of the year, if it had 47 days. You can ask for negative
days as well, obviously there is no such thing as a negative day. It's
useful because people do date math with these functions.

Is it really that unreasonable to do the same "scaling" in the case of
daylight saving time? Should everyone who writes for the arguably proper
behavior of other systems have to put in a workaround for FreeBSD's DST
blackout? It's not just 1 second, it's a whole missing hour, every year
after 1986, it's a little different before that. I know that in the case
of my PHP programs, I'd have to wrap mktime again just for one operating
system.

What's the argument to keep it this way?
Comment 6 Harrison Grundy 2014-12-17 12:32:07 UTC
Closed as Not a Bug per https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=15520