aboutsummaryrefslogtreecommitdiff
path: root/src/common/time_zone.cpp
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
commitefeb79f380934b58b8d0f27167c5682e77efb41f (patch)
treedcfb079c4a47d112a37be6185ef1a1f93e774f73 /src/common/time_zone.cpp
parent5137c8ad74a9b2d12d00e73afc53c1297aee8ac5 (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.
Diffstat (limited to 'src/common/time_zone.cpp')
-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