Skip to content

Commit dd3e11a

Browse files
Merge pull request #148 from ParsePlatform/richardross.timezone.fix
Fix TimeZone mappings for Windows Phone and Unity
2 parents b801a6e + dcf4c2a commit dd3e11a

File tree

3 files changed

+59
-13
lines changed

3 files changed

+59
-13
lines changed

Parse/Internal/PlatformHooks/Phone/PlatformHooks.Phone.cs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -151,16 +151,26 @@ public string DeviceType {
151151
public string DeviceTimeZone {
152152
get {
153153
// We need the system string to be in english so we'll have the proper key in our lookup table.
154-
var culture = Thread.CurrentThread.CurrentCulture;
155-
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
156-
string windowsName = TimeZoneInfo.Local.StandardName;
157-
Thread.CurrentThread.CurrentCulture = culture;
154+
// If it's not in english then we will attempt to fallback to the closest Time Zone we can find.
155+
TimeZoneInfo tzInfo = TimeZoneInfo.Local;
158156

159-
if (ParseInstallation.TimeZoneNameMap.ContainsKey(windowsName)) {
160-
return ParseInstallation.TimeZoneNameMap[windowsName];
161-
} else {
162-
return null;
157+
string deviceTimeZone = null;
158+
if (ParseInstallation.TimeZoneNameMap.TryGetValue(tzInfo.StandardName, out deviceTimeZone)) {
159+
return deviceTimeZone;
160+
}
161+
162+
TimeSpan utcOffset = tzInfo.BaseUtcOffset;
163+
164+
// If we have an offset that is not a round hour, then use our second map to see if we can
165+
// convert it or not.
166+
if (ParseInstallation.TimeZoneOffsetMap.TryGetValue(utcOffset, out deviceTimeZone)) {
167+
return deviceTimeZone;
163168
}
169+
170+
// NOTE: Etc/GMT{+/-} format is inverted from the UTC offset we use as normal people -
171+
// a negative value means ahead of UTC, a positive value means behind UTC.
172+
bool negativeOffset = utcOffset.Ticks < 0;
173+
return String.Format("Etc/GMT{0}{1}", negativeOffset ? "+" : "-", Math.Abs(utcOffset.Hours));
164174
}
165175
}
166176

Parse/Internal/PlatformHooks/Unity/PlatformHooks.Unity.cs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,27 @@ public string DeviceType {
8888
public string DeviceTimeZone {
8989
get {
9090
try {
91-
string windowsName = TimeZoneInfo.Local.StandardName;
92-
if (ParseInstallation.TimeZoneNameMap.ContainsKey(windowsName)) {
93-
return ParseInstallation.TimeZoneNameMap[windowsName];
94-
} else {
95-
return null;
91+
// We need the system string to be in english so we'll have the proper key in our lookup table.
92+
// If it's not in english then we will attempt to fallback to the closest Time Zone we can find.
93+
TimeZoneInfo tzInfo = TimeZoneInfo.Local;
94+
95+
string deviceTimeZone = null;
96+
if (ParseInstallation.TimeZoneNameMap.TryGetValue(tzInfo.StandardName, out deviceTimeZone)) {
97+
return deviceTimeZone;
9698
}
99+
100+
TimeSpan utcOffset = tzInfo.BaseUtcOffset;
101+
102+
// If we have an offset that is not a round hour, then use our second map to see if we can
103+
// convert it or not.
104+
if (ParseInstallation.TimeZoneOffsetMap.TryGetValue(utcOffset, out deviceTimeZone)) {
105+
return deviceTimeZone;
106+
}
107+
108+
// NOTE: Etc/GMT{+/-} format is inverted from the UTC offset we use as normal people -
109+
// a negative value means ahead of UTC, a positive value means behind UTC.
110+
bool negativeOffset = utcOffset.Ticks < 0;
111+
return String.Format("Etc/GMT{0}{1}", negativeOffset ? "+" : "-", Math.Abs(utcOffset.Hours));
97112
} catch (TimeZoneNotFoundException) {
98113
return null;
99114
}

Parse/Public/ParseInstallation.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,5 +352,26 @@ internal override Task SaveAsync(Task toAwait, CancellationToken cancellationTok
352352
{"Tonga Standard Time", "Pacific/Tongatapu"},
353353
{"Samoa Standard Time", "Pacific/Apia"}
354354
};
355+
356+
/// <summary>
357+
/// This is a mapping of odd TimeZone offsets to their respective IANA codes across the world.
358+
/// This list was compiled from painstakingly pouring over the information available at
359+
/// https://en.wikipedia.org/wiki/List_of_tz_database_time_zones.
360+
/// </summary>
361+
internal static readonly Dictionary<TimeSpan, String> TimeZoneOffsetMap = new Dictionary<TimeSpan, string>() {
362+
{ new TimeSpan(12, 45, 0), "Pacific/Chatham" },
363+
{ new TimeSpan(10, 30, 0), "Australia/Lord_Howe" },
364+
{ new TimeSpan(9, 30, 0), "Australia/Adelaide" },
365+
{ new TimeSpan(8, 45, 0), "Australia/Eucla" },
366+
{ new TimeSpan(8, 30, 0), "Asia/Pyongyang" }, // Parse in North Korea confirmed.
367+
{ new TimeSpan(6, 30, 0), "Asia/Rangoon" },
368+
{ new TimeSpan(5, 45, 0), "Asia/Kathmandu" },
369+
{ new TimeSpan(5, 30, 0), "Asia/Colombo" },
370+
{ new TimeSpan(4, 30, 0), "Asia/Kabul" },
371+
{ new TimeSpan(3, 30, 0), "Asia/Tehran" },
372+
{ new TimeSpan(-3, 30, 0), "America/St_Johns" },
373+
{ new TimeSpan(-4, 30, 0), "America/Caracas" },
374+
{ new TimeSpan(-9, 30, 0), "Pacific/Marquesas" },
375+
};
355376
}
356377
}

0 commit comments

Comments
 (0)