Jacky Sun
Jacky Sun

Reputation: 11

Why localtime() gives different timezone on the same machine?

As the title said, below is the code. The timezone in the output will be changed according to the value of "tmt".

Environment:

[/tmp@16:01]uname -a
Linux ubuntu 3.13.0-100-generic #147-Ubuntu SMP Tue Oct 18 16:48:51 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

Code:

#include <stdio.h>
#include <time.h>
#include <strings.h>

#define LOCKOUT_TIME_FORMAT     "%Y-%m-%dT%H:%M:%S%z"

int main()
{
        time_t tmt = 0;
        time_t tmt1 = 0;
        struct tm * ptm = NULL;
        char str[128] = {0};


        time(&tmt1);
        ptm = localtime(&tmt1);
        strftime(str, sizeof(str), LOCKOUT_TIME_FORMAT, ptm);
        printf("time1 is %s\n", str);

        //tmt=3600 * 24 * 30;                       //one month
        //tmt=3600 * 24 * 30 * 6;                   //about six month
        //tmt=3600 * 24 * 30 * 12;                  //about one year
        //tmt=3600 * 24 * 30 * 12 * 10;             //about ten years
        //tmt=3600 * 24 * 30 * 12 * 11;             //about 11 years
        tmt=3600 * 24 * 30 * 12 * 20;               //about 20 years

        ptm = localtime(&tmt);
        strftime(str, sizeof(str), LOCKOUT_TIME_FORMAT, ptm);
        printf("time is %s\n", str);

        return 0;
}

When tmt=3600 * 24 * 30 * 12 * 20, the output timezone of tmt and tmt1 will be the same.

[/tmp@15:58]./a.out 
time1 is 2017-03-23T15:58:20-0700
time is 1989-09-17T17:00:00-0700

When tmt is other values commented out in the code, the output timezone of tmt and tmt1 will be different!

[/tmp@16:01]./a.out 
time1 is 2017-03-23T16:01:07-0700
time is 1980-11-03T16:00:00-0800

Personally, I think the timezone should be the same since the code is run on the same machine. Why the timezone changes as the value of time?

Thanks,

Upvotes: 1

Views: 1374

Answers (1)

Vadim Barkov
Vadim Barkov

Reputation: 41

localtime() handles summer time transitions properly.
The date you entered int tmt variable is one of the summer days while the current date is not a summer day.
I suggest this output format for testing ("%Z" means "The timezone name or abbreviation")
#define LOCKOUT_TIME_FORMAT "%Y-%m-%dT%H:%M:%S\t|%Z"

Results:

$ TZ="Europe/Moscow" ./test
time1 is 2017-03-24T03:01:07    |MSK
time is 1989-09-18T04:00:00     |MSD

MSK is Moscow "regular" time and MSD means Moscow Summer Time.

This is known as Daylight Saving Time.

Upvotes: 2

Related Questions