Skip to content
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] Trim TimeZoneInfo to reduce size #50266

Merged
merged 2 commits into from
Mar 30, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,14 @@ set(NATIVEGLOBALIZATION_SOURCES
pal_localeNumberData.c
pal_localeStringData.c
pal_normalization.c
pal_timeZoneInfo.c
pal_icushim.c
)

# time zone names are filtered out of icu data for the browser and associated functionality is disabled
if (NOT CLR_CMAKE_TARGET_BROWSER)
set(NATIVEGLOBALIZATION_SOURCES ${NATIVEGLOBALIZATION_SOURCES} pal_timeZoneInfo.c)
endif()

if (NOT GEN_SHARED_LIB AND NOT CLR_CMAKE_TARGET_MACCATALYST AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS AND NOT CLR_CMAKE_TARGET_ANDROID AND NOT CLR_CMAKE_TARGET_BROWSER)
set(NATIVEGLOBALIZATION_SOURCES ${NATIVEGLOBALIZATION_SOURCES} entrypoints.c)
endif()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1096,10 +1096,10 @@
<Compile Include="$(CommonPath)Interop\Interop.ResultCode.cs">
<Link>Common\Interop\Interop.ResultCode.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Interop.TimeZoneDisplayNameType.cs">
<Compile Include="$(CommonPath)Interop\Interop.TimeZoneDisplayNameType.cs" Condition="'$(TargetsBrowser)' != 'true'" >
<Link>Common\Interop\Interop.TimeZoneDisplayNameType.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Interop.TimeZoneInfo.cs">
<Compile Include="$(CommonPath)Interop\Interop.TimeZoneInfo.cs" Condition="'$(TargetsBrowser)' != 'true'" >
<Link>Common\Interop\Interop.TimeZoneInfo.cs</Link>
</Compile>
<Compile Include="$(CommonPath)Interop\Interop.Utils.cs">
Expand Down Expand Up @@ -1909,7 +1909,6 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Environment.Browser.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\DriveInfoInternal.Browser.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\IO\PersistedFiles.Browser.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\TimeZoneInfo.GetDisplayName.cs" />
</ItemGroup>
<ItemGroup Condition="'$(IsOSXLike)' == 'true'">
<Compile Include="$(CommonPath)Interop\OSX\Interop.libobjc.cs">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,22 @@ public sealed partial class TimeZoneInfo
private const string ZoneTabFileName = "zone.tab";
private const string TimeZoneEnvironmentVariable = "TZ";
private const string TimeZoneDirectoryEnvironmentVariable = "TZDIR";

#if !TARGET_BROWSER
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why browser only? We use the same data on other platforms like tvOS

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a list of targets that use the filtered ICU data? Or a different flag I should use?

These can all be trimmed out, anywhere that the full ICU with time zone data is not available.

mattjohnsonpint marked this conversation as resolved.
Show resolved Hide resolved
private const string FallbackCultureName = "en-US";
private const string GmtId = "GMT";

// Some time zones may give better display names using their location names rather than their generic name.
// We can update this list as need arises.
private static readonly string[] s_ZonesThatUseLocationName = new[] {
"Europe/Minsk", // Prefer "Belarus Time" over "Moscow Standard Time (Minsk)"
"Europe/Moscow", // Prefer "Moscow Time" over "Moscow Standard Time"
"Europe/Simferopol", // Prefer "Simferopol Time" over "Moscow Standard Time (Simferopol)"
"Pacific/Apia", // Prefer "Samoa Time" over "Apia Time"
"Pacific/Pitcairn" // Prefer "Pitcairn Islands Time" over "Pitcairn Time"
};
#endif

// UTC aliases per https://github.com/unicode-org/cldr/blob/master/common/bcp47/timezone.xml
// Hard-coded because we need to treat all aliases of UTC the same even when ICU is not available,
// or when we get "GMT" returned from older ICU versions. (This list is not likely to change.)
Expand All @@ -39,16 +52,6 @@ public sealed partial class TimeZoneInfo
"Zulu"
};

// Some time zones may give better display names using their location names rather than their generic name.
// We can update this list as need arises.
private static readonly string[] s_ZonesThatUseLocationName = new[] {
"Europe/Minsk", // Prefer "Belarus Time" over "Moscow Standard Time (Minsk)"
"Europe/Moscow", // Prefer "Moscow Time" over "Moscow Standard Time"
"Europe/Simferopol", // Prefer "Simferopol Time" over "Moscow Standard Time (Simferopol)"
"Pacific/Apia", // Prefer "Samoa Time" over "Apia Time"
"Pacific/Pitcairn" // Prefer "Pitcairn Islands Time" over "Pitcairn Time"
};

private TimeZoneInfo(byte[] data, string id, bool dstDisabled)
{
_id = id;
Expand Down Expand Up @@ -119,6 +122,11 @@ private TimeZoneInfo(byte[] data, string id, bool dstDisabled)
_daylightDisplayName = daylightAbbrevName ?? standardAbbrevName;
_displayName = _standardDisplayName;

#if TARGET_BROWSER
// For the browser, ICU time zone data is filtered out. The standard and daylight names will use the abbreviations set above,
// and the display name is composed of just the offset and IANA time zone ID (except UTC which is handled elsewhere).
_displayName = $"(UTC{(_baseUtcOffset >= TimeSpan.Zero ? '+' : '-')}{_baseUtcOffset:hh\\:mm}) {_id}";
#else
// Determine the culture to use
CultureInfo uiCulture = CultureInfo.CurrentUICulture;
if (uiCulture.Name.Length == 0)
Expand All @@ -128,6 +136,7 @@ private TimeZoneInfo(byte[] data, string id, bool dstDisabled)
GetDisplayName(_id, Interop.Globalization.TimeZoneDisplayNameType.Standard, uiCulture.Name, ref _standardDisplayName);
GetDisplayName(_id, Interop.Globalization.TimeZoneDisplayNameType.DaylightSavings, uiCulture.Name, ref _daylightDisplayName);
GetFullValueForDisplayNameField(_id, _baseUtcOffset, uiCulture, ref _displayName);
#endif

// TZif supports seconds-level granularity with offsets but TimeZoneInfo only supports minutes since it aligns
// with DateTimeOffset, SQL Server, and the W3C XML Specification
Expand All @@ -145,7 +154,8 @@ private TimeZoneInfo(byte[] data, string id, bool dstDisabled)
ValidateTimeZoneInfo(_id, _baseUtcOffset, _adjustmentRules, out _supportsDaylightSavingTime);
}

// Helper function that builds the value backing the DisplayName field from gloablization data.
#if !TARGET_BROWSER
// Helper function that builds the value backing the DisplayName field from globalization data.
private static void GetFullValueForDisplayNameField(string timeZoneId, TimeSpan baseUtcOffset, CultureInfo uiCulture, ref string? displayName)
{
// There are a few diffent ways we might show the display name depending on the data.
Expand All @@ -159,7 +169,6 @@ private static void GetFullValueForDisplayNameField(string timeZoneId, TimeSpan
// Try to get the generic name for this time zone.
string? genericName = null;
GetDisplayName(timeZoneId, Interop.Globalization.TimeZoneDisplayNameType.Generic, uiCulture.Name, ref genericName);

if (genericName == null)
{
// When we can't get a generic name, use the offset and the ID.
Expand Down Expand Up @@ -271,6 +280,7 @@ private static string GetExemplarCityName(string timeZoneId, string uiCultureNam
int i = timeZoneId.LastIndexOf('/');
return timeZoneId.Substring(i + 1).Replace('_', ' ');
}
#endif

// The TransitionTime fields are not used when AdjustmentRule.NoDaylightTransitions == true.
// However, there are some cases in the past where DST = true, and the daylight savings offset
Expand Down Expand Up @@ -382,6 +392,7 @@ private static void PopulateAllSystemTimeZones(CachedData cachedData)

private static unsafe string? GetAlternativeId(string id)
{
#if !TARGET_BROWSER
if (!GlobalizationMode.Invariant)
{
if (id.Equals("utc", StringComparison.OrdinalIgnoreCase))
Expand All @@ -406,7 +417,7 @@ private static void PopulateAllSystemTimeZones(CachedData cachedData)
return new string(buffer, 0, length);
}
}

#endif
return null;
}

Expand Down Expand Up @@ -1965,6 +1976,9 @@ private static bool StringArrayContains(string value, string[] source, StringCom
// Helper function to get the standard display name for the UTC static time zone instance
private static string GetUtcStandardDisplayName()
{
#if TARGET_BROWSER
return InvariantUtcStandardDisplayName;
#else
// Don't bother looking up the name for invariant or English cultures
CultureInfo uiCulture = CultureInfo.CurrentUICulture;
if (GlobalizationMode.Invariant || uiCulture.Name.Length == 0 || uiCulture.TwoLetterISOLanguageName == "en")
Expand All @@ -1979,6 +1993,7 @@ private static string GetUtcStandardDisplayName()
standardDisplayName = InvariantUtcStandardDisplayName;

return standardDisplayName;
#endif
}
}
}