Bug 150168

Summary: Erratic behaviour of mktime()
Product: Red Hat Enterprise Linux 3 Reporter: David Juran <djuran>
Component: glibcAssignee: Jakub Jelinek <jakub>
Status: CLOSED NOTABUG QA Contact: Brian Brock <bbrock>
Severity: medium Docs Contact:
Priority: medium    
Version: 3.0CC: drepper.fsp
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2005-03-19 22:58:58 EST Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---
Attachments:
Description Flags
Program used to demonstrate behaviour none

Description David Juran 2005-03-03 03:12:58 EST
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4.3)
Gecko/20050104 Red Hat/1.4.3-3.0.7

Description of problem:
The function mktime() builds a time_t from a struct tm.
The result of converting a time that falls in the hour
when dayligth savings time ends is erratic in that it
depends on what conversions have been performed earlier.

Background.
The struct tm contains fields for specifying year, month etc.
It also has a field, tm_isdst, for specifying if daylight
savings time is in effect. This field may be assigned
>0 to mean daylight savings time, 0 for normal time or <0 to
indicate "information not available".

When dayligth savings time ends the local time jumps back
so for a sort interval (1 hour) the same local times are repeated.
If a time from that interval is converted to time_t (UTC) the
function needs to decide if the local time specified in the struct tm
refers to daylight savings time or normal time. If the tm_isdst
field is negative there is no information available to make
that decision, so for that period the data is ambiguous.

On RHEL the mktime() function remembers earlier conversions so
if a preceeding conversion referred to a normal time then the
ambigous one will be treated as normal but if the preceeding
conversion referred to daylight savings time the ambiguous one
will be treated as savings time too.
Therefore: the outcome of a conversion depends on the actual data
of earlier conversions so the outcome of one call cannot be predicted
based on the arguments alone.

References:
This behaviour is not documented in the man-page for mktime() nor is
it specified in ISO/IEC 9899-1999 C-standard.
Furthermore: tested implementations on SunOS, HP-UX and IBM-AIX do
not suffer from this unpredictability.

Version-Release number of selected component (if applicable):
glibc-2.3.2-95.30

How reproducible:
Always

Steps to Reproduce:
1. compile the attached test-case
2. watch how test -s and test -n gives differing results

    

Additional info:
Comment 1 David Juran 2005-03-03 03:14:50 EST
Created attachment 111608 [details]
Program used to demonstrate behaviour

The program compiles with g++ on RHEL, xlC on AIX, aCC on HPUX and CC on SunOs.


Run with argument -s or -n to see effect of preceeding conversion on
savings time data or normal time data.
The output should be identical (esp. the Time=xxx) for both -s and -n flags.

If the DST change in your locale did not occur on the compiled-in date
31oct2004 you may specify another date on format dd mm yyyy,
e.g. for Christmas Eve say:
a.out -n 24 12 2005
Comment 2 Jakub Jelinek 2005-03-14 09:05:49 EST
Well, both POSIX and ISO C99 say:
A negative value causes it to attempt to determine whether Daylight Saving Time
is in effect for the specified time.
so I don't see glibc's mktime to violate this, as both tm_isdst = 0 and
tm_isdst = 1 on output are IMHO conformant answers.
mktime in glibc uses static variable localtime_offset that tracks last mktime
GMT offset with the primary purpose to speed up conversion in the common case.
Comment 3 Ulrich Drepper 2005-03-19 22:58:58 EST
We are not catering to individual users' wishes if there is no standard
violation.  The current behavior is likely relied on by others.  If you want no
surprises, but do anything which creates them.