-
Notifications
You must be signed in to change notification settings - Fork 5.3k
[Android][libs] Introduce GetLocalUtcOffset temporary fast result #74459
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
a3f0e9f
a44084a
1edaeee
0712f57
96bf37f
582c359
9a2a8a2
f352b3a
f7dc8e9
32451c8
1a55a0c
61af7b7
50ff121
b1531b6
533ad1c
ef7729e
55fcccc
1cfc352
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -107,7 +107,7 @@ private static int ParseGMTNumericZone(string name) | |
| { | ||
| return new TimeZoneInfo(id, TimeSpan.FromSeconds(0), id, name, name, null, disableDaylightSavingTime:true); | ||
| } | ||
| if (name.StartsWith("GMT", StringComparison.Ordinal)) | ||
| if (name[0] == 'G' && name[1] == 'M' && name[2] == 'T') | ||
| { | ||
| return new TimeZoneInfo(id, TimeSpan.FromSeconds(ParseGMTNumericZone(name)), id, name, name, null, disableDaylightSavingTime:true); | ||
| } | ||
|
|
@@ -142,6 +142,56 @@ private static TimeZoneInfo GetLocalTimeZoneCore() | |
| return Utc; | ||
| } | ||
|
|
||
| private static TimeSpan GetCacheLocalUtcOffset(DateTime dateTime, TimeZoneInfoOptions flags) | ||
| { | ||
| CachedData cachedData = s_cachedData; | ||
| return cachedData.Local.GetUtcOffset(dateTime, flags, cachedData); | ||
mdh1418 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| private static TimeSpan? _localUtcOffset; | ||
mdh1418 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| private static object _localUtcOffsetLock = new(); | ||
| private static Thread? _loadAndroidTZData; | ||
mdh1418 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| // Shortcut for TimeZoneInfo.Local.GetUtcOffset | ||
| // On Android, loading AndroidTZData while obtaining cachedData.Local is expensive for startup. | ||
| // We introduce a fast result for GetLocalUtcOffset that relies on the date time offset being | ||
| // passed into monovm_initialize(_preparsed) from Java in seconds as LOCAL_DATE_TIME_OFFSET. | ||
| // However, to handle timezone changes during the app lifetime, AndroidTZData needs to be loaded. | ||
| // The fast path is initially used, and we start a background thread to get cachedData.Local | ||
| internal static TimeSpan GetLocalUtcOffset(DateTime dateTime, TimeZoneInfoOptions flags) | ||
| { | ||
| if (_localUtcOffset != null) // The background thread finished, the cache is loaded. | ||
| return GetCacheLocalUtcOffset(dateTime, flags); | ||
|
|
||
| if (_localUtcOffset == null && _loadAndroidTZData == null) // The cache isn't loaded and no background thread has been created | ||
| { | ||
| lock (_localUtcOffsetLock) | ||
| { | ||
| // GetLocalUtcOffset may be called multiple times before a cache is loaded and a background thread is running, | ||
| // once the lock is available, check for a cache and background thread. | ||
| if (_localUtcOffset != null) | ||
| return GetCacheLocalUtcOffset(dateTime, flags); | ||
|
|
||
| if (_loadAndroidTZData == null) | ||
| { | ||
| _loadAndroidTZData = new Thread(() => { | ||
| Thread.Sleep(1000); | ||
|
||
| _localUtcOffset = GetCacheLocalUtcOffset(dateTime, flags); | ||
| }); | ||
| _loadAndroidTZData.IsBackground = true; | ||
| _loadAndroidTZData.Start(); | ||
mdh1418 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
| } | ||
| } | ||
|
|
||
| object? localDateTimeOffset = AppContext.GetData("LOCAL_DATE_TIME_OFFSET"); | ||
mdh1418 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| if (localDateTimeOffset == null) | ||
| return GetCacheLocalUtcOffset(dateTime, flags); // If no offset property provided through monovm app context, default | ||
|
|
||
| long localDateTimeOffsetSeconds = Convert.ToInt32(localDateTimeOffset); | ||
mdh1418 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| TimeSpan offset = TimeSpan.FromSeconds(localDateTimeOffsetSeconds); | ||
| return offset; | ||
| } | ||
|
|
||
| private static TimeZoneInfoResult TryGetTimeZoneFromLocalMachineCore(string id, out TimeZoneInfo? value, out Exception? e) | ||
| { | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.