Created
July 25, 2018 09:00
-
-
Save igrr/9d55a9c2e625722acd05ad2020cb6fa5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <time.h> | |
#include <sys/time.h> | |
#include <assert.h> | |
static time_t get_tz_offset(time_t now) { | |
struct tm local, utc; | |
localtime_r(&now, &local); | |
gmtime_r(&now, &utc); | |
time_t time_diff = local.tm_sec - utc.tm_sec + | |
+ (local.tm_min - utc.tm_min) * 60 | |
+ (local.tm_hour - utc.tm_hour) * 3600; | |
const int day_diff = local.tm_mday - utc.tm_mday; | |
const time_t one_day = 24 * 3600; | |
if (day_diff == 1) { | |
// local is ahead of UTC | |
time_diff += one_day; | |
} else if (day_diff < -1) { | |
// local is ahead of UTC and at month boundary | |
time_diff += one_day; | |
} else if (day_diff == -1) { | |
// local is behind UTC | |
time_diff -= one_day; | |
} else if (day_diff > 1) { | |
// local is behind UTC and at month boundary | |
time_diff -= one_day; | |
} | |
return time_diff; | |
} | |
static time_t timestamp_to_unix_time(const char* time_str) | |
{ | |
struct tm tm_parsed; | |
const char* end = strptime(time_str, "%Y-%m-%dT%H:%M:%S", &tm_parsed); | |
if (end == NULL) { | |
assert(false && "parse error in strptime"); | |
} | |
int tz_hour, tz_min; | |
if (sscanf(end, "%d:%d", &tz_hour, &tz_min) != 2) { | |
assert(false && "parse error in sscanf"); | |
} | |
time_t remote_tz_offset = tz_hour * 3600 + tz_min * 60; | |
// At this point, tm_parsed contains local time in timezone | |
// indicated by remote_tz_offset. | |
// Current time | |
time_t now = time(NULL); | |
// offset between local time and UTC | |
time_t local_tz_offset = get_tz_offset(now); | |
// difference between local and remote time zones, in seconds | |
time_t total_tz_diff = local_tz_offset - remote_tz_offset; | |
// adjust tm structure from remote to local timezone | |
return mktime(&tm_parsed) + total_tz_diff; | |
} | |
void app_main() | |
{ | |
// set local time and timezone | |
// in real application time would be set using SNTP | |
setenv("TZ", "MDT-3", 1); | |
tzset(); | |
const char* now_str = "2018-07-25T11:00:00"; | |
struct tm tm_now; | |
strptime(now_str, "%Y-%m-%dT%H:%M:%S", &tm_now); | |
time_t t_now = mktime(&tm_now); | |
struct timeval tv_now = { | |
.tv_sec = t_now | |
}; | |
settimeofday(&tv_now, NULL); | |
// Time stamp to get time until | |
const char* time_str = "2018-07-25T11:00:00-05:00"; | |
printf("Time until %s: %d sec\n", time_str, (int) (timestamp_to_unix_time(time_str) - t_now)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment