summaryrefslogtreecommitdiff
path: root/src/common/time_zone.cpp
diff options
context:
space:
mode:
authorGravatar lat9nq2023-07-10 17:51:34 -0400
committerGravatar lat9nq2023-07-10 17:51:34 -0400
commit90d76333da843f7058ff527bae0bdceaa1d3cd69 (patch)
treedcfb079c4a47d112a37be6185ef1a1f93e774f73 /src/common/time_zone.cpp
parentMerge pull request #11067 from t895/fragile-data (diff)
downloadyuzu-90d76333da843f7058ff527bae0bdceaa1d3cd69.tar.gz
yuzu-90d76333da843f7058ff527bae0bdceaa1d3cd69.tar.xz
yuzu-90d76333da843f7058ff527bae0bdceaa1d3cd69.zip
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 d8d7896c6..a25f8b040 100644
--- a/src/common/time_zone.cpp
+++ b/src/common/time_zone.cpp
@@ -33,32 +33,27 @@ std::string GetDefaultTimeZone() {
33 return "GMT"; 33 return "GMT";
34} 34}
35 35
36static std::string GetOsTimeZoneOffset() { 36// Results are not comparable to seconds since Epoch
37 const std::time_t t{std::time(nullptr)}; 37static std::time_t TmSpecToSeconds(const struct std::tm& spec) {
38 const std::tm tm{*std::localtime(&t)}; 38 std::time_t cumulative = spec.tm_year;
39 39 cumulative = cumulative * 365 + spec.tm_yday; // Years to days
40 return fmt::format("{:%z}", tm); 40 cumulative = cumulative * 24 + spec.tm_hour; // Days to hours
41} 41 cumulative = cumulative * 60 + spec.tm_min; // Hours to minutes
42 42 cumulative = cumulative * 60 + spec.tm_sec; // Minutes to seconds
43static int ConvertOsTimeZoneOffsetToInt(const std::string& timezone) { 43 return cumulative;
44 try {
45 return std::stoi(timezone);
46 } catch (const std::invalid_argument&) {
47 LOG_CRITICAL(Common, "invalid_argument with {}!", timezone);
48 return 0;
49 } catch (const std::out_of_range&) {
50 LOG_CRITICAL(Common, "out_of_range with {}!", timezone);
51 return 0;
52 }
53} 44}
54 45
55std::chrono::seconds GetCurrentOffsetSeconds() { 46std::chrono::seconds GetCurrentOffsetSeconds() {
56 const int offset{ConvertOsTimeZoneOffsetToInt(GetOsTimeZoneOffset())}; 47 const std::time_t t{std::time(nullptr)};
48 const std::tm local{*std::localtime(&t)};
49 const std::tm gmt{*std::gmtime(&t)};
57 50
58 int seconds{(offset / 100) * 60 * 60}; // Convert hour component to seconds 51 // gmt_seconds is a different offset than time(nullptr)
59 seconds += (offset % 100) * 60; // Convert minute component to seconds 52 const auto gmt_seconds = TmSpecToSeconds(gmt);
53 const auto local_seconds = TmSpecToSeconds(local);
54 const auto seconds_offset = gmt_seconds - local_seconds;
60 55
61 return std::chrono::seconds{seconds}; 56 return std::chrono::seconds{seconds_offset};
62} 57}
63 58
64// Key is [Hours * 100 + Minutes], multiplied by 100 if DST 59// Key is [Hours * 100 + Minutes], multiplied by 100 if DST
@@ -71,11 +66,6 @@ const static std::map<s64, const char*> off_timezones = {
71}; 66};
72 67
73std::string FindSystemTimeZone() { 68std::string FindSystemTimeZone() {
74#if defined(MINGW)
75 // MinGW has broken strftime -- https://sourceforge.net/p/mingw-w64/bugs/793/
76 // e.g. fmt::format("{:%z}") -- returns "Eastern Daylight Time" when it should be "-0400"
77 return timezones[0];
78#else
79 const s64 seconds = static_cast<s64>(GetCurrentOffsetSeconds().count()); 69 const s64 seconds = static_cast<s64>(GetCurrentOffsetSeconds().count());
80 70
81 const s64 minutes = seconds / 60; 71 const s64 minutes = seconds / 60;
@@ -97,7 +87,6 @@ std::string FindSystemTimeZone() {
97 } 87 }
98 } 88 }
99 return fmt::format("Etc/GMT{:s}{:d}", hours > 0 ? "-" : "+", std::abs(hours)); 89 return fmt::format("Etc/GMT{:s}{:d}", hours > 0 ? "-" : "+", std::abs(hours));
100#endif
101} 90}
102 91
103} // namespace Common::TimeZone 92} // namespace Common::TimeZone