I would like to know the time as seconds from the era. It is noteworthy that I would not want to matter where the machine performing the conversion should be sufficient for the time zone line.
I have this test program, pt.cc:
#include <assert.h>
#include <errno.h>
#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE
#endif
#include <time.h>
using namespace std;
int main(int argc, char* argv[]) {
(void)argc; (void)argv;
cout << "1440671500 expected" << endl;
const char utc_example[] = "2015-08-27T11:31:40+0100";
struct tm tm;
memset(&tm, 0, sizeof(struct tm));
char* end = strptime(utc_example, "%Y-%m-%dT%H:%M:%S%z", &tm);
assert(end);
assert(*end == '\0');
time_t seconds_since_epoch = mktime(&tm);
cout << "utc example: " << seconds_since_epoch << " or maybe "
<< seconds_since_epoch - tm.tm_gmtoff + (tm.tm_isdst ? 3600 : 0) << endl;
const char tz_example[] = "2015-08-27T10:31:40Z";
memset(&tm, 0, sizeof(struct tm));
end = strptime(tz_example, "%Y-%m-%dT%H:%M:%S%nZ", &tm);
assert(end);
assert(*end == '\0');
seconds_since_epoch = mktime(&tm);
cout << " tz example: " << seconds_since_epoch << " or maybe "
<< seconds_since_epoch - tm.tm_gmtoff + (tm.tm_isdst ? 3600 : 0) << endl;
return 0;
}
This is the conclusion:
jeff@birdsong:tmp $ clang++ -ggdb3 -Wall -Wextra -std=c++14 pt.cc -o pt
jeff@birdsong:tmp $ ./pt
1440671500 expected
utc example: 1440671500 or maybe 1440667900
tz example: 1440667900 or maybe 1440664300
jeff@birdsong:tmp $ TZ=America/New_York ./pt
1440671500 expected
utc example: 1440693100 or maybe 1440711100
tz example: 1440689500 or maybe 1440707500
jeff@birdsong:tmp $ TZ=Europe/London ./pt
1440671500 expected
utc example: 1440675100 or maybe 1440675100
tz example: 1440671500 or maybe 1440671500
jeff@birdsong:tmp $
Notice how the return value changes mktime()
depending on the surrounding time zone. The man page entry for mktime()
assumes that it interprets the breakdown time as local time. So I tried to subtract the GMT offset and compensate for the time zone if it ignores these values (the value "or maybe").
Any tips on how to do this correctly? (If that matters, I only need this to work on Linux.)