Skip to content

Instantly share code, notes, and snippets.

@w1ndy
Last active November 23, 2023 07:40
Show Gist options
  • Save w1ndy/763c514428e8a7f6481e to your computer and use it in GitHub Desktop.
Save w1ndy/763c514428e8a7f6481e to your computer and use it in GitHub Desktop.
Lock-free version of mktime (converting "struct tm" to UNIX timestamp) without considering timezone
#pragma once
#include <cassert>
#include <ctime>
#define ISLEAP(x) (((x) % 4 == 0 && (x) % 100 != 0) || ((x) % 400 == 0))
#define LEAPDELTA(x, y) ((ISLEAP(x) && (y) >= 2) ? 86400 : 0)
time_t mktime_quick(struct tm const &p)
{
const time_t residual[4] = {0, 31536000, 63072000, 94694400};
const time_t month[12] = {0, 2678400, 5097600, 7776000, 10368000,
13046400, 15638400, 18316800, 20995200, 23587200, 26265600,
28857600};
time_t y = p.tm_year - 70;
y = (y >> 2) * 126230400 + residual[y & 3];
assert(p.tm_mon >= 0 && p.tm_mon < 12 && "month out of range");
time_t m = month[p.tm_mon] + LEAPDELTA(p.tm_year, p.tm_mon);
time_t d = 86400 * (p.tm_mday - 1);
time_t t = 3600 * p.tm_hour + 60 * p.tm_min + p.tm_sec;
return y + m + d + t;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment