Since glibc 2.28.9000-17.fc30, there is the following regression in mktime: ======== #include <stdlib.h> #include <stdio.h> #include <time.h> #include <error.h> int main () { int ret; struct tm info; char buffer[80]; info.tm_year = 2012 - 1900; info.tm_mon = 3 - 1; info.tm_mday = 12; info.tm_hour = 1; info.tm_min = 1; info.tm_sec = 0; info.tm_isdst = 1; ret = mktime(&info); if( ret == -1 ) { perror("Error: unable to make time using mktime"); return(1); } else { strftime(buffer, sizeof(buffer), "%c\n", &info ); printf(buffer); return(0); } } ======== Use `gcc filename.c` to compile it: With older glibc: $ TZ=CET ./a.out Mon Mar 12 00:01:00 2012 $ TZ=CEST ./a.out Mon Mar 12 01:01:00 2012 $ TZ=UTC ./a.out Mon Mar 12 01:01:00 2012 With new glibc: $ TZ=CET ./a.out Mon Mar 12 00:01:00 2012 $ TZ=CEST ./a.out Error: unable to make time using mktime: Value too large for defined data type $ TZ=UTC ./a.out Error: unable to make time using mktime: Value too large for defined data type
Context: test_email of Python 3.7.1 started to fail on Fedora Rawhide. I reported the bug upstream: https://bugs.python.org/issue35317
(In reply to Miro Hrončok from comment #0) > info.tm_isdst = 1; > $ TZ=CET ./a.out > Mon Mar 12 00:01:00 2012 > $ TZ=CEST ./a.out > Error: unable to make time using mktime: Value too large for defined data > type > $ TZ=UTC ./a.out > Error: unable to make time using mktime: Value too large for defined data > type The behavior is at least inconsistent because there is no DST in effect at this time in all three cases, so tm_isdst == 1 is invalid input.
I'm not sure that it's a bug. mktime() fails with TZ=UTC on the same date on FreeBSD since 2012 (FreeBSD 8.2, I can reproduce the bug on FreeBSD 12.0-RC2): https://bugs.python.org/issue35317#msg330443 Moreover, I proposed a fix for test_email of Python: https://github.com/python/cpython/pull/10721
(In reply to Florian Weimer from comment #2) > (In reply to Miro Hrončok from comment #0) > > info.tm_isdst = 1; > > > $ TZ=CET ./a.out > > Mon Mar 12 00:01:00 2012 > > $ TZ=CEST ./a.out > > Error: unable to make time using mktime: Value too large for defined data > > type > > $ TZ=UTC ./a.out > > Error: unable to make time using mktime: Value too large for defined data > > type > > The behavior is at least inconsistent because there is no DST in effect at > this time in all three cases, so tm_isdst == 1 is invalid input. CEST is with DST. The S stands for Summer as in daylight saving.
(In reply to Miro Hrončok from comment #4) > (In reply to Florian Weimer from comment #2) > > (In reply to Miro Hrončok from comment #0) > > > info.tm_isdst = 1; > > > > > $ TZ=CET ./a.out > > > Mon Mar 12 00:01:00 2012 > > > $ TZ=CEST ./a.out > > > Error: unable to make time using mktime: Value too large for defined data > > > type > > > $ TZ=UTC ./a.out > > > Error: unable to make time using mktime: Value too large for defined data > > > type > > > > The behavior is at least inconsistent because there is no DST in effect at > > this time in all three cases, so tm_isdst == 1 is invalid input. > > CEST is with DST. The S stands for Summer as in daylight saving. Ah, that explains it. CEST is actually an alias for UTC.
CEST is UTC+2.
(In reply to Miro Hrončok from comment #6) > CEST is UTC+2. No, CEST is an alias for UTC as far as the time zone database is concerned. Time zone names actually look like Europe/Berlin. The abbreviations are not unique and usually do not work at all.
> The abbreviations are not unique and usually do not work at all. Oh, OK. Sorry.
We also ran into this problem, so I've reported it upstream: https://sourceware.org/bugzilla/show_bug.cgi?id=24630
Upstream indicated that the behavior with UTC and tm_isdst == 1 is expected.