Reputation: 73
I am trying to get the local time in seconds (unix epoch) when a timezone is set. For e.g.
1643371200 is 2022-01-28 12:00:00 with UTC0
this can be read via gettimeofday(tv, NULL) as seconds with the timeval struct.
Now let's say I set my local timezone to Europe/Berlin via setenv("TZ","CET-1CEST,M3.5.0,M10.5.0/3",1).
When I use
localtime_r(&now, &local_tv);
char strftime_buf[64];
strftime(strftime_buf, sizeof(strftime_buf), "%c", &local_tv);
printf("get local time: %s", strftime_buf);
this prints 2022-01-28 13:00:00 as expected (+1h).
Now I used mktime(&local_tv) as I thought this will give me my local time in seconds. But it's still 1643371200 (12:00:00). And when I use mktime() with gettimeofday() I get 1 hour less, so 11:00:00 ...
Upvotes: 1
Views: 1049
Reputation: 386706
So why is
mktime()
giving me1643371200
when used withlocaltime_r()
2022-01-28T13:00:00+01:00 is 1643371200 seconds later than 1970-01-01T00:00:00+00:00, the epoch used on Linux.
mktime
is literally the inverse operation of localtime
, so of course mktime(localtime(time)) gives time.
time /
gettimeofday
|
+-----------------+-----------------+
| | |
| v |
| Epoch time |
| | |
| +------+------+ |
| | | |
| v v |
| localtime gmtime |
| | | |
| v v |
| Broken down Broken down |
| local time UTC+0 time |
| | | |
| v v |
| mktime / _mkgmtime* / |
| timelocal* timegm* |
| | | |
+----------+ +----------+
how do I get 1643374800 ?
You appear to want the number of seconds since 1970-01-01T00:00:00 local time.
If you want this, you are doing something wrong. There is no need for this value.[1]
To find the number of seconds between two times, start by converting them to epoch times if they aren't already. Then simply subtract one from the other.
#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <time.h>
int main( void ) {
setenv( "TZ", "Europe/Berlin", 1 );
tzset();
struct tm base_tm = {
.tm_sec = 0, /* Seconds (0-60) */
.tm_min = 0, /* Minutes (0-59) */
.tm_hour = 0, /* Hours (0-23) */
.tm_mday = 1, /* Day of the month (1-31) */
.tm_mon = 1 - 1, /* Month (0-11) */
.tm_year = 1970 - 1900, /* Year - 1900 */
//.tm_wday = , /* Day of the week (0-6, Sunday = 0) */
//.tm_yday = , /* Day in the year (0-365, 1 Jan = 0) */
.tm_isdst = -1 /* Daylight saving time */
};
time_t base_epoch = mktime( &base_tm );
time_t now_epoch = 1643371200l; // time( NULL );
printf( "%" PRIi64 "\n", (int64_t)( now_epoch - base_epoch ) ); // 1643374800
}
Upvotes: 1