Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mktime and tm_isdst flag

Tags:

c++

I have the following doubt on the usage of tm_isdst flag in the tm structure. As per man pages and googled results, I understand that its value is interpreted as follows

A. A value of 0 indicates DST is not in effect for the represented time

B. A value of 1 indicates DST is in effect

C. A value of -1 causes mktime to check whether DST is in effect or not.

It is this third point which is confusing me. My doubt is how mktime can figure out whether DST has to be applied or not accurately.

For example

My Time Zone = GMT + 3:00
DST shifting = +1 Hour at 5:00 AM in January (to keep it simple)
Current UTC time = "01/Jan/2012 00:00:00"
UTC time in seconds time_t timetUTC = X seconds
Hence my time is = "01/Jan/2012 03:00:00"

As time passes, my time value changes as follows

"01/Jan/2012 04:00:00"            (X + 1 * 60 * 60)
"01/Jan/2012 05:00:00"            (X + 2 * 60 * 60)
"01/Jan/2012 05:59:59"            (X + 2 * 60 * 60 + 59)
"01/Jan/2012 05:00:00"            (X + 3 * 60 * 60)
"01/Jan/2012 06:00:00"            (X + 4 * 60 * 60)

As per my understanding

tm tmMyTime = localtime_r(X + 2 * 60 * 60) will set tmMyTime.tm_isdst to 0
tm tmMyTime = localtime_r(X + 3 * 60 * 60) will set tmMyTime.tm_isdst to 1

This way, even though all other components of tm structure are equal in both cases, mktime(tmMyTime) can return proper UTC value, depending on tm_isdst value.

Now, if I set tmMyTime.tm_isdst = -1, what value would mktime return? I read about TZ variable, time database etc etc. In spite of all that, logically how can mktime() figure out whether to apply DST correction or not for those tm values that can occur twice?

We do not have DST in our time zone. Hence I am not very sure whether my understanding is correct. Please correct me if I am wrong. Your help is much appreciated.

like image 284
programmist Avatar asked May 10 '12 11:05

programmist


3 Answers

In short: it is implementation dependent.

mktime knows the DST rules by checking the locale.

For the bigger part of the year, mktime can figure out if DST is to be applied for a particular local time. The problem is indeed the "duplicate" hour when DST shifts backwards (in your example 05:00:00 - 05:59:59). For this local time range, given tm_isdst = -1, mktime cannot know if DST is in effect or not. Which one of these is chosen, differs from one implementation to another. With the GNU version of mktime, the UTC before the shift is returned.

like image 67
Pat Avatar answered Oct 05 '22 22:10

Pat


tm_isdst cannot in general resolve ambiguous times. That's because many timezones have transitions (one-time) without jumping from dst to nodst, just changing offset and zone abbreviation. So both times (before and after transition) have the same tm_isdst. Some other zones changes tm_isdst when switching summer/winter time but doesn't change abbreviation (Australia/Melbourne for example).

like image 27
Pronin Oleg Avatar answered Oct 05 '22 23:10

Pronin Oleg


I think it's going to be somewhat dependent on your platform. In Windows, at least, the mktime() documentation states "The C run-time library assumes the United States’s rules for implementing the calculation of Daylight Saving Time", so it has a table of rules somewhere where it can determine when DST started / ended in any given year.

You're lucky not to have DST where you are. In my world, which is real-time data acquisition and presentation, DST is a big nuisance!

like image 37
pnswdv Avatar answered Oct 06 '22 00:10

pnswdv