3

I'm now writing a C program on my RedHat Linux Machine using gcc compiler, which will accept two dates as input and compute the difference between them.

However, I found a strange behavior with the mktime() as illustrated with below code segment.


struct tm t;
t.tm_year=4;
t.tm_mon=9;
t.tm_mday=30;
t.tm_hour=0;
t.tm_min=0;
t.tm_sec=0;

printf("%d-%d-%d %d:%d:%d\n", t.tm_year, t.tm_mon, t.tm_day, t.tm_hour, t.tm_min, t.tm_sec);
//result: 4-9-30 0:0:0, which means 1904 Oct 30 00:00:00

mktime(&t);

printf("%d-%d-%d %d:%d:%d\n", t.tm_year, t.tm_mon, t.tm_day, t.tm_hour, t.tm_min, t.tm_sec);
//result: 4-9-29 23:36:36, which means 1904 Oct 29 23:36:36

As you can see the struct tm was shifted after mktime() which looks unreasonable.

I have done a lot of testing, and I found this strange behavior happens only for date assignment between 1904 Oct 30 00:00:00 - 00:23:24.

Besides, I have tested the same codes in my unix server (HP-UX), and it runs perfectly without any shifting.

I wonder if anyone have similar experience before, if anyone can give me hints on what's going on?

I'm running in the Hong Kong time zone.

herbertng
  • 53
  • 3

1 Answers1

6

The mktime() function assumes that the input represents local time. There have been a number of strange shifts in local time in various locations at various times.

It would be helpful to know what your time zone is. If you set your time zone to UTC, I suspect the problem will go away.

I don't see this issue myself (I'm in Pacific Daylight Time, 7 hours west of UTC).

This looks similar to a time shift in June of that same year in Luxembourg, documented here, when local clocks were shifted forward by 35 minutes and 24 seconds. 30 October 1904 was a Sunday, which is a likely time for such a shift.

See also this question concerning a time change in Shanghai in 1927 (which happens to have Jon Skeet's highest-scoring answer).

UPDATE: Found it, thanks to Frxstrem's comment. There was a time change in Hong Kong on October 30, 1904, from LMT to HKT. I'd expect the symptom to show up if (a) your time zone is set to Hong Kong time, and (b) your system's time zone library is detailed enough to reflect this particular change.

http://www.timeanddate.com/time/change/hong-kong/hong-kong?year=1904


Here's a modified version of your program that shows the issue a bit more clearly:

#include <time.h>
#include <stdio.h>
int main(void) {
    struct tm t = {
        .tm_year  = 4,
        .tm_mon   = 9,
        .tm_mday  = 30,
        .tm_hour  = 0,
        .tm_min   = 0,
        .tm_sec   = 0,
        .tm_isdst = -1, /* let mktime() figure it out */
    };

    printf("%04d-%02d-%02d %02d:%02d:%02d\n",
           1900+t.tm_year, 1+t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
    // output: 1904-10-30 00:00:00

    mktime(&t);

    printf("%04d-%02d-%02d %02d:%02d:%02d\n",
           1900+t.tm_year, 1+t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
    // output: 1904-10-29 23:36:42
}

It assigns a value to the tm_isdst member, which yours doesn't do; with an uninitialized value, you can have unpredictable behavior. Also, your program misspelled tm_mday as tm_day.

Here's the output on my system:

$ ./c
1904-10-30 00:00:00
1904-10-30 00:00:00
$ TZ=Asia/Hong_Kong ./c
1904-10-30 00:00:00
1904-10-29 23:36:42
$ 

Some background on how I was able to figure this out fairly quickly (which might be helpful to others seeing similar symptoms):

The question strongly reminded me of this one, which I'm familiar with only because it has the highest-scoring answer by the highest-scoring user on Stack Overflow. That was pure luck.

Since I initially didn't know the time zone, a Google search for "1904 time change" turned up this page discussing a similar time change the same year in Luxembourg. It's plausible that other parts of the world did similar changes around the same time, probably as part of the transition to modern standard time zones.

Frxstrem's comment nailed it: a Google search for "1904 Hong Kong time change" found this page.

Community
  • 1
  • 1
Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
  • 2
    Indeed, on [October 30, 1904 at 00:00:00](http://www.timeanddate.com/time/change/hong-kong/hong-kong?year=1904) the clocks in Hong Kong were turned forward 23 hours and 24 seconds to be exactly 8 hours ahead of GMT. – Frxstrem Jul 25 '14 at 18:50
  • Thanks a lot Keith and Frxstrem, you guys are brilliant! Yes I am running with Hong Kong Timezone, and your answers just give me the exact reason of the shift. Let me try with the UTC timezone as suggested and see the behavior. Thank you very much again. – herbertng Jul 25 '14 at 19:12