-
-
Save anba/14f2a7982f5010dbae90bb3509774ced 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
// See https://searchfox.org/mozilla-central/source/js/src/vm/DateTime.cpp | |
#include <cstddef> | |
#include <cstdint> | |
#include <cstdlib> | |
#include <cstring> | |
#include <time.h> | |
#include <iostream> | |
#if !defined(XP_WIN) | |
# include <limits.h> | |
# include <unistd.h> | |
#endif /* !defined(XP_WIN) */ | |
#define HAVE_LOCALTIME_R 1 | |
static bool ComputeLocalTime(time_t local, struct tm* ptm) { | |
#if defined(_WIN32) | |
return localtime_s(ptm, &local) == 0; | |
#elif defined(HAVE_LOCALTIME_R) | |
return localtime_r(&local, ptm); | |
#else | |
struct tm* otm = localtime(&local); | |
if (!otm) { | |
return false; | |
} | |
*ptm = *otm; | |
return true; | |
#endif | |
} | |
static bool ComputeUTCTime(time_t t, struct tm* ptm) { | |
#if defined(_WIN32) | |
return gmtime_s(ptm, &t) == 0; | |
#elif defined(HAVE_GMTIME_R) | |
return gmtime_r(&t, ptm); | |
#else | |
struct tm* otm = gmtime(&t); | |
if (!otm) { | |
return false; | |
} | |
*ptm = *otm; | |
return true; | |
#endif | |
} | |
static int32_t UTCToLocalStandardOffsetSeconds() { | |
constexpr double SecondsPerMinute = 60; | |
constexpr unsigned SecondsPerHour = 60 * 60; | |
constexpr unsigned SecondsPerDay = SecondsPerHour * 24; | |
time_t currentMaybeWithDST = time(nullptr); | |
if (currentMaybeWithDST == time_t(-1)) { | |
return 0; | |
} | |
struct tm local; | |
if (!ComputeLocalTime(currentMaybeWithDST, &local)) { | |
return 0; | |
} | |
time_t currentNoDST; | |
if (local.tm_isdst == 0) { | |
currentNoDST = currentMaybeWithDST; | |
} else { | |
struct tm localNoDST = local; | |
localNoDST.tm_isdst = 0; | |
currentNoDST = mktime(&localNoDST); | |
if (currentNoDST == time_t(-1)) { | |
return 0; | |
} | |
} | |
struct tm utc; | |
if (!ComputeUTCTime(currentNoDST, &utc)) { | |
return 0; | |
} | |
int utc_secs = utc.tm_hour * SecondsPerHour + utc.tm_min * SecondsPerMinute; | |
int local_secs = local.tm_hour * SecondsPerHour + local.tm_min * SecondsPerMinute; | |
if (utc.tm_mday == local.tm_mday) { | |
return local_secs - utc_secs; | |
} | |
if (utc_secs > local_secs) { | |
return (SecondsPerDay + local_secs) - utc_secs; | |
} | |
return local_secs - (utc_secs + SecondsPerDay); | |
} | |
int main() { | |
do { | |
std::cout << "current time zone offset: " << UTCToLocalStandardOffsetSeconds() << std::endl; | |
} while (std::cin.get() == '\n'); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment