@ -1,7 +1,15 @@
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
# if __cpp_lib_chrono >= 201907L
# include <chrono>
# else
# include <ctime>
# include <limits>
# endif
# include <string_view>
# include <fmt/chrono.h>
# include <fmt/core.h>
# include "common/assert.h"
# include "common/fs/path_util.h"
@ -15,7 +23,7 @@ static bool configuring_global = true;
std : : string GetTimeZoneString ( ) {
static constexpr std : : array timezones {
" auto" , " default " , " CET " , " CST6CDT " , " Cuba " , " EET " , " Egypt " , " Eire " ,
" GMT" , " GMT " , " CET " , " CST6CDT " , " Cuba " , " EET " , " Egypt " , " Eire " ,
" EST " , " EST5EDT " , " GB " , " GB-Eire " , " GMT " , " GMT+0 " , " GMT-0 " , " GMT0 " ,
" Greenwich " , " Hongkong " , " HST " , " Iceland " , " Iran " , " Israel " , " Jamaica " , " Japan " ,
" Kwajalein " , " Libya " , " MET " , " MST " , " MST7MDT " , " Navajo " , " NZ " , " NZ-CHAT " ,
@ -25,7 +33,73 @@ std::string GetTimeZoneString() {
const auto time_zone_index = static_cast < std : : size_t > ( values . time_zone_index . GetValue ( ) ) ;
ASSERT ( time_zone_index < timezones . size ( ) ) ;
return timezones [ time_zone_index ] ;
std : : string location_name ;
switch ( time_zone_index ) {
case 0 : { // Auto
# if __cpp_lib_chrono >= 201907L
const struct std : : chrono : : tzdb & time_zone_data = std : : chrono : : get_tzdb ( ) ;
const std : : chrono : : time_zone * current_zone = time_zone_data . current_zone ( ) ;
std : : string_view current_zone_name = current_zone - > name ( ) ;
location_name = current_zone_name ;
# elif 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"
location_name = timezones [ 0 ] ;
break ;
# else
static constexpr std : : array offsets {
0 , 0 , 3600 , - 21600 , - 19768 , 7200 , 7509 , - 1521 , - 18000 , - 18000 ,
- 75 , - 75 , 0 , 0 , 0 , 0 , 0 , 27402 , - 36000 , - 968 ,
12344 , 8454 , - 18430 , 33539 , 40160 , 3164 , 3600 , - 25200 , - 25200 , - 25196 ,
41944 , 44028 , 5040 , - 2205 , 29143 , - 28800 , 29160 , 30472 , 24925 , 6952 ,
0 , 0 , 0 , 9017 , 0 , 0 ,
} ;
static constexpr std : : array dst {
false , false , true , true , true , true , true , true , false , true , true , true ,
false , false , false , false , false , true , false , false , true , true , true , true ,
false , true , true , false , true , true , true , true , true , true , true , true ,
true , true , true , true , false , false , false , true , true , false ,
} ;
const auto now = std : : time ( nullptr ) ;
const struct std : : tm & local = * std : : localtime ( & now ) ;
const std : : string clock_offset_s = fmt : : format ( " {:%z} " , local ) ;
if ( clock_offset_s . empty ( ) ) {
location_name = timezones [ 0 ] ;
break ;
}
const int hours_offset = std : : stoi ( clock_offset_s ) / 100 ;
const int minutes_offset = std : : stoi ( clock_offset_s ) - hours_offset * 100 ;
const int system_offset =
hours_offset * 3600 + minutes_offset * 60 - ( local . tm_isdst ? 3600 : 0 ) ;
int min = std : : numeric_limits < int > : : max ( ) ;
int min_index = - 1 ;
for ( u32 i = 2 ; i < offsets . size ( ) ; i + + ) {
// Skip if system is celebrating DST but considered time zone does not
if ( local . tm_isdst & & ! dst [ i ] ) {
continue ;
}
const auto offset = offsets [ i ] ;
const int difference = std : : abs ( std : : abs ( offset ) - std : : abs ( system_offset ) ) ;
if ( difference < min ) {
min = difference ;
min_index = i ;
}
}
location_name = timezones [ min_index ] ;
# endif
break ;
}
default :
location_name = timezones [ time_zone_index ] ;
break ;
}
return location_name ;
}
void LogSettings ( ) {