aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlat9nq <22451773+lat9nq@users.noreply.github.com>2023-07-10 17:51:34 -0400
committerlat9nq <22451773+lat9nq@users.noreply.github.com>2023-07-10 17:51:34 -0400
commit90d76333da843f7058ff527bae0bdceaa1d3cd69 (patch)
treedcfb079c4a47d112a37be6185ef1a1f93e774f73
parente32ce6cc6980fd468280f6e8148cfccdb9853990 (diff)
time_zone: Remove string ops for determing zone
MinGW's strftime implementation does not work and cannot be used to determine the time zone. Besides that, the string operations are actually unnecessary since we can get the offset from std::localtime. Compare localtime to gmtime to find the zone offset on all platforms.
-rw-r--r--src/common/time_zone.cpp43
1 files changed, 16 insertions, 27 deletions
diff --git a/src/common/time_zone.cpp b/src/common/time_zone.cpp
index d8d7896c61..a25f8b040d 100644
--- a/src/common/time_zone.cpp
+++ b/src/common/time_zone.cpp
@@ -33,32 +33,27 @@ std::string GetDefaultTimeZone() {
return "GMT";
}
-static std::string GetOsTimeZoneOffset() {
- const std::time_t t{std::time(nullptr)};
- const std::tm tm{*std::localtime(&t)};
-
- return fmt::format("{:%z}", tm);
-}
-
-static int ConvertOsTimeZoneOffsetToInt(const std::string& timezone) {
- try {
- return std::stoi(timezone);
- } catch (const std::invalid_argument&) {
- LOG_CRITICAL(Common, "invalid_argument with {}!", timezone);
- return 0;
- } catch (const std::out_of_range&) {
- LOG_CRITICAL(Common, "out_of_range with {}!", timezone);
- return 0;
- }
+// Results are not comparable to seconds since Epoch
+static std::time_t TmSpecToSeconds(const struct std::tm& spec) {
+ std::time_t cumulative = spec.tm_year;
+ cumulative = cumulative * 365 + spec.tm_yday; // Years to days
+ cumulative = cumulative * 24 + spec.tm_hour; // Days to hours
+ cumulative = cumulative * 60 + spec.tm_min; // Hours to minutes
+ cumulative = cumulative * 60 + spec.tm_sec; // Minutes to seconds
+ return cumulative;
}
std::chrono::seconds GetCurrentOffsetSeconds() {
- const int offset{ConvertOsTimeZoneOffsetToInt(GetOsTimeZoneOffset())};
+ const std::time_t t{std::time(nullptr)};
+ const std::tm local{*std::localtime(&t)};
+ const std::tm gmt{*std::gmtime(&t)};
- int seconds{(offset / 100) * 60 * 60}; // Convert hour component to seconds
- seconds += (offset % 100) * 60; // Convert minute component to seconds
+ // gmt_seconds is a different offset than time(nullptr)
+ const auto gmt_seconds = TmSpecToSeconds(gmt);
+ const auto local_seconds = TmSpecToSeconds(local);
+ const auto seconds_offset = gmt_seconds - local_seconds;
- return std::chrono::seconds{seconds};
+ return std::chrono::seconds{seconds_offset};
}
// Key is [Hours * 100 + Minutes], multiplied by 100 if DST
@@ -71,11 +66,6 @@ const static std::map<s64, const char*> off_timezones = {
};
std::string FindSystemTimeZone() {
-#if defined(MINGW)
- // MinGW has broken strftime -- https://sourceforge.net/p/mingw-w64/bugs/793/
- // e.g. fmt::format("{:%z}") -- returns "Eastern Daylight Time" when it should be "-0400"
- return timezones[0];
-#else
const s64 seconds = static_cast<s64>(GetCurrentOffsetSeconds().count());
const s64 minutes = seconds / 60;
@@ -97,7 +87,6 @@ std::string FindSystemTimeZone() {
}
}
return fmt::format("Etc/GMT{:s}{:d}", hours > 0 ? "-" : "+", std::abs(hours));
-#endif
}
} // namespace Common::TimeZone