@@ -72,7 +72,12 @@ module Crystal::System::Time
72
72
def self.load_localtime : ::Time ::Location ?
73
73
if LibC .GetDynamicTimeZoneInformation (out info) != LibC ::TIME_ZONE_ID_INVALID
74
74
windows_name = String .from_utf16(info.timeZoneKeyName.to_slice, truncate_at_null: true )
75
- initialize_location_from_TZI(pointerof (info).as(LibC ::TIME_ZONE_INFORMATION * ).value, " Local" , windows_name)
75
+
76
+ return unless canonical_iana_name = windows_to_iana[windows_name]?
77
+ return unless windows_info = iana_to_windows[canonical_iana_name]?
78
+ _, stdname, dstname = windows_info
79
+
80
+ initialize_location_from_TZI(pointerof (info).as(LibC ::TIME_ZONE_INFORMATION * ).value, " Local" , windows_name, stdname, dstname)
76
81
end
77
82
end
78
83
@@ -90,7 +95,8 @@ module Crystal::System::Time
90
95
daylightDate : LibC ::SYSTEMTIME
91
96
92
97
def self.load_iana_zone (iana_name : String ) : ::Time ::Location ?
93
- return unless windows_name = iana_to_windows[iana_name]?
98
+ return unless windows_info = iana_to_windows[iana_name]?
99
+ windows_name, stdname, dstname = windows_info
94
100
95
101
WindowsRegistry .open?(LibC ::HKEY_LOCAL_MACHINE , REGISTRY_TIME_ZONES ) do |key_handle |
96
102
WindowsRegistry .open?(key_handle, windows_name.to_utf16) do |sub_handle |
@@ -106,14 +112,12 @@ module Crystal::System::Time
106
112
)
107
113
WindowsRegistry .get_raw(sub_handle, Std , tzi.standardName.to_slice.to_unsafe_bytes)
108
114
WindowsRegistry .get_raw(sub_handle, Dlt , tzi.daylightName.to_slice.to_unsafe_bytes)
109
- initialize_location_from_TZI(tzi, iana_name, windows_name)
115
+ initialize_location_from_TZI(tzi, iana_name, windows_name, stdname, dstname )
110
116
end
111
117
end
112
118
end
113
119
114
- private def self.initialize_location_from_TZI (info , name , windows_name )
115
- stdname, dstname = normalize_zone_names(info)
116
-
120
+ private def self.initialize_location_from_TZI (info , name , windows_name , stdname , dstname )
117
121
if info.standardDate.wMonth == 0 _u16 || info.daylightDate.wMonth == 0 _u16
118
122
# No DST
119
123
zone = ::Time ::Location ::Zone .new(stdname, info.bias * BIAS_TO_OFFSET_FACTOR , false )
@@ -140,27 +144,6 @@ module Crystal::System::Time
140
144
::Time ::TZ ::MonthWeekDay .new(time.wMonth.to_i8, time.wDay.to_i8, time.wDayOfWeek.to_i8, seconds)
141
145
end
142
146
143
- # Normalizes the names of the standard and dst zones.
144
- private def self.normalize_zone_names (info : LibC ::TIME_ZONE_INFORMATION ) : Tuple (String , String )
145
- stdname, _ = String .from_utf16(info.standardName.to_slice.to_unsafe)
146
-
147
- if normalized_names = windows_zone_names[stdname]?
148
- return normalized_names
149
- end
150
-
151
- dstname, _ = String .from_utf16(info.daylightName.to_slice.to_unsafe)
152
-
153
- if english_name = translate_zone_name(stdname, dstname)
154
- if normalized_names = windows_zone_names[english_name]?
155
- return normalized_names
156
- end
157
- end
158
-
159
- # As a last resort, return the raw names as provided by TIME_ZONE_INFORMATION.
160
- # They are most probably localized and we couldn't find a translation.
161
- return stdname, dstname
162
- end
163
-
164
147
REGISTRY_TIME_ZONES = System .wstr_literal %q( SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones)
165
148
Std = System .wstr_literal " Std"
166
149
Dlt = System .wstr_literal " Dlt"
0 commit comments