-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
[WASM] new trimmer feature System.TimeZoneInfo.Invariant #111215
base: main
Are you sure you want to change the base?
Conversation
Tagging subscribers to this area: @dotnet/area-system-globalization |
Will it be acceptable to have |
It will report UTC. Also this behavior already existed before this PR, here I'm just removing the ability to load TZ data from file system, when |
Thanks. I am not sure my question is answered :-) I am not questioning the PR more than questioning behavior. I guess users haven't run into this yet to report it. Returning UTC time when having TZ settings different than UTC is questionable. Maybe it is acceptable to the browser (especially servers) but wanted to know how we validated this assumption. |
src/tools/illink/src/ILLink.Tasks/build/Microsoft.NET.ILLink.targets
Outdated
Show resolved
Hide resolved
This is not how it works. You would not be able to change to non-UTC timezone. Let me show you: given code Console.WriteLine($"TimeZoneInfo.Local is {TimeZoneInfo.Local}");
Console.WriteLine($"DateTime.UtcNow is {DateTime.UtcNow}");
Console.WriteLine($"DateTime.Now is {DateTime.Now}");
var start = DateTime.UtcNow;
var timezonesCount = TimeZoneInfo.GetSystemTimeZones().Count;
await Delay(100);
var end = DateTime.UtcNow;
Console.WriteLine($"Found {timezonesCount} timezones in the TZ database in {end - start}");
TimeZoneInfo utc = TimeZoneInfo.FindSystemTimeZoneById("UTC");
Console.WriteLine($"{utc.DisplayName} BaseUtcOffset is {utc.BaseUtcOffset}");
try
{
TimeZoneInfo tst = TimeZoneInfo.FindSystemTimeZoneById("Asia/Tokyo");
Console.WriteLine($"{tst.DisplayName} BaseUtcOffset is {tst.BaseUtcOffset}");
}
catch (TimeZoneNotFoundException tznfe)
{
Console.WriteLine($"Could not find Asia/Tokyo: {tznfe.Message}");
} At 12:19 in Prague, you will get following output
|
The On the browser "operating system" we don't have TZ database pre-installed and so we are bundling it with each application. It's 300KB of download and some CPU time before the runtime can start. That's a lot for a web app, especially if your business logic is not about dates/times/calendars. Before this PR the I feel quite safe to make this change for the browser target. @steveisok is this how it works for iOS too ? Can I assume people are not shipping custom |
We don't ship anything custom on iOS or Android as we rely on whatever they do. |
b5ce502
to
48ccc77
Compare
} | ||
``` | ||
|
||
3. setting environment variable value `DOTNET_SYSTEM_TIMEZONE_INVARIANT` to `true` or `1`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the expected precedence if someone sets <InvariantTimezone>true</InvariantTimezone>
and DOTNET_SYSTEM_TIMEZONE_INVARIANT=false
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AppContextConfigHelper.GetBooleanConfig (which Invariant Globalization uses) checks the env var first, and then the runtimeconfig:
runtime/src/libraries/System.Private.CoreLib/src/System/AppContextConfigHelper.cs
Lines 13 to 29 in 058fe35
internal static bool GetBooleanConfig(string switchName, string envVariable, bool defaultValue = false) | |
{ | |
string? str = Environment.GetEnvironmentVariable(envVariable); | |
if (str != null) | |
{ | |
if (str == "1" || bool.IsTrueStringIgnoreCase(str)) | |
{ | |
return true; | |
} | |
if (str == "0" || bool.IsFalseStringIgnoreCase(str)) | |
{ | |
return false; | |
} | |
} | |
return GetBooleanConfig(switchName, defaultValue); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<InvariantTimezone>true</InvariantTimezone>
will trigger linker to substitute the call to GetBooleanConfig
to constant true
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So with trimming, <InvariantTimezone>true</InvariantTimezone>
wins, and without trimming, DOTNET_SYSTEM_TIMEZONE_INVARIANT=false
wins. Is that the behavior we want? Typically we try to avoid behavior changes introduced by trimming.
@@ -48,6 +48,7 @@ public TrimmingArgumentBuilder (TestCaseMetadataProvider metadataProvider) | |||
Options.FeatureSwitches.Add ("System.Text.Encoding.EnableUnsafeUTF7Encoding", false); | |||
Options.FeatureSwitches.Add ("System.Diagnostics.Tracing.EventSource.IsSupported", false); | |||
Options.FeatureSwitches.Add ("System.Globalization.Invariant", true); | |||
Options.FeatureSwitches.Add ("System.TimeZoneInfo.Invariant", true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not necessary, we only put here whatever switches are enabled by default in an empty console app.
@@ -40,6 +40,7 @@ | |||
<ReproResponseLines Include="--feature:System.Linq.Expressions.CanEmitObjectArrayDelegate=false" /> | |||
<ReproResponseLines Include="--feature:System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported=false" /> | |||
<ReproResponseLines Include="--feature:System.Globalization.Invariant=true" /> | |||
<ReproResponseLines Include="--feature:System.TimeZoneInfo.Invariant=true" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, not necessary.
Should this switch be respected on other platforms too? I know it will not lead to real size savings, but consistency is quite important. Feature switches are problematic in general because they change behavior of code that was unit tested or used elsewhere without the feature switch being set: there might be subtle bugs introduced by the feature switch that bypassed quality gates. Making the feature switch effect as visible as possible helps to at least somewhat mitigate that. |
Motivation: when
TryGetLocalTzFile
is included it brings dependency toSystem.IO.File
and its dependencies.System.TimeZoneInfo.Invariant
triggered by existing<InvariantTimezone>true</InvariantTimezone>
System.TimeZoneInfo.Invariant
getter also driven byDOTNET_SYSTEM_TIMEZONE_INVARIANT
env variableILLink.Substitutions.LegacyJsInterop.xml
Together with dotnet/sdk#45792
<InvariantTimezone>true</InvariantTimezone>
is pre-existing feature.