From b429e70c935a6cc919e3bdcaa3375d8ace514ea1 Mon Sep 17 00:00:00 2001 From: Sergio Pedri Date: Tue, 7 May 2024 11:13:37 -0700 Subject: [PATCH] Add 'CsWinRTUseUtcDateTimeOffsetMarshalling' switch --- nuget/Microsoft.Windows.CsWinRT.targets | 6 +++++ .../Configuration/FeatureSwitches.cs | 25 ++++++++++++++++--- .../Configuration/ILLink.Substitutions.xml | 4 +++ src/WinRT.Runtime/Projections/SystemTypes.cs | 10 ++++++++ 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/nuget/Microsoft.Windows.CsWinRT.targets b/nuget/Microsoft.Windows.CsWinRT.targets index 4d60abd31..555dc0d00 100644 --- a/nuget/Microsoft.Windows.CsWinRT.targets +++ b/nuget/Microsoft.Windows.CsWinRT.targets @@ -251,6 +251,7 @@ $(CsWinRTInternalProjection) true false + false true true true @@ -272,6 +273,11 @@ $(CsWinRTInternalProjection) + + + /// The configuration property name for . /// - private const string EnablesDynamicObjectsSupportPropertyName = "CSWINRT_ENABLE_DYNAMIC_OBJECTS_SUPPORT"; + private const string EnableDynamicObjectsSupportPropertyName = "CSWINRT_ENABLE_DYNAMIC_OBJECTS_SUPPORT"; /// - /// The configuration property name for . + /// The configuration property name for . /// private const string UseExceptionResourceKeysPropertyName = "CSWINRT_USE_EXCEPTION_RESOURCE_KEYS"; + /// + /// The configuration property name for . + /// + private const string UseUtcDateTimeOffsetMarshallingPropertyName = "CSWINRT_USE_UTC_DATETIMEOFFSET_MARSHALLING"; + /// /// The configuration property name for . /// @@ -61,6 +66,11 @@ internal static class FeatureSwitches /// private static int _useExceptionResourceKeys; + /// + /// The backing field for . + /// + private static int _useUtcDateTimeOffsetMarshalling; + /// /// The backing field for . /// @@ -87,7 +97,7 @@ internal static class FeatureSwitches public static bool EnableDynamicObjectsSupport { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => GetConfigurationValue(EnablesDynamicObjectsSupportPropertyName, ref _enableDynamicObjectsSupportEnabled, true); + get => GetConfigurationValue(EnableDynamicObjectsSupportPropertyName, ref _enableDynamicObjectsSupportEnabled, true); } /// @@ -99,6 +109,15 @@ public static bool UseExceptionResourceKeys get => GetConfigurationValue(UseExceptionResourceKeysPropertyName, ref _useExceptionResourceKeys, false); } + /// + /// Gets a value indicating whether or not values should be marshalled as UTC (defaults to ). + /// + public static bool UseUtcDateTimeOffsetMarshalling + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => GetConfigurationValue(UseUtcDateTimeOffsetMarshallingPropertyName, ref _useUtcDateTimeOffsetMarshalling, false); + } + /// /// Gets a value indicating whether or not should initialize all default type mappings automatically (defaults to ). /// diff --git a/src/WinRT.Runtime/Configuration/ILLink.Substitutions.xml b/src/WinRT.Runtime/Configuration/ILLink.Substitutions.xml index 8a04a92b3..cfaaf5110 100644 --- a/src/WinRT.Runtime/Configuration/ILLink.Substitutions.xml +++ b/src/WinRT.Runtime/Configuration/ILLink.Substitutions.xml @@ -10,6 +10,10 @@ + + + + diff --git a/src/WinRT.Runtime/Projections/SystemTypes.cs b/src/WinRT.Runtime/Projections/SystemTypes.cs index aebcdf4b8..2b2bc9d64 100644 --- a/src/WinRT.Runtime/Projections/SystemTypes.cs +++ b/src/WinRT.Runtime/Projections/SystemTypes.cs @@ -3,6 +3,7 @@ using System; using System.Runtime.InteropServices; +using WinRT; namespace ABI.System { @@ -86,6 +87,15 @@ public static Marshaler CreateMarshaler(global::System.DateTimeOffset value) public static global::System.DateTimeOffset FromAbi(DateTimeOffset value) { var utcTime = new global::System.DateTimeOffset(value.UniversalTime + ManagedUtcTicksAtNativeZero, global::System.TimeSpan.Zero); + + if (FeatureSwitches.UseUtcDateTimeOffsetMarshalling) + { + return utcTime; + } + + // Backwards-compat: validate the local time and return that instead of the UTC one. + // We can't make this the default behavior, as people might have taken a dependency + // on this, since it's been here for quite a while. So, we have a feature switch instead. var offset = TimeZoneInfo.Local.GetUtcOffset(utcTime); long localTicks = utcTime.Ticks + offset.Ticks; if (localTicks < DateTime.MinValue.Ticks || localTicks > DateTime.MaxValue.Ticks)