Skip to content

Instantly share code, notes, and snippets.

@igrr
Created July 25, 2018 09:00
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save igrr/9d55a9c2e625722acd05ad2020cb6fa5 to your computer and use it in GitHub Desktop.
#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