From b3331a417ec22734a83f7139bd22ebd35f091af4 Mon Sep 17 00:00:00 2001 From: Genevieve Warren <24882762+gewarren@users.noreply.github.com> Date: Thu, 2 Nov 2023 20:24:03 -0700 Subject: [PATCH] cbor breaking change (#37881) --- docs/core/compatibility/8.0.md | 21 +++-- .../extensions/8.0/cbor-datetime.md | 94 +++++++++++++++++++ docs/core/compatibility/toc.yml | 4 + 3 files changed, 109 insertions(+), 10 deletions(-) create mode 100644 docs/core/compatibility/extensions/8.0/cbor-datetime.md diff --git a/docs/core/compatibility/8.0.md b/docs/core/compatibility/8.0.md index ccfcc9818f226..6ade2b75d867d 100644 --- a/docs/core/compatibility/8.0.md +++ b/docs/core/compatibility/8.0.md @@ -78,16 +78,17 @@ If you're migrating an app to .NET 8, the breaking changes listed here might aff ## Extensions -| Title | Type of change | Introduced | -|-----------------------------------------------------------------------------------------------------------------------------------|-------------------|------------| -| [ActivatorUtilities.CreateInstance behaves consistently](extensions/8.0/activatorutilities-createinstance-behavior.md) | Behavioral change | Preview 1 | -| [ActivatorUtilities.CreateInstance requires non-null provider](extensions/8.0/activatorutilities-createinstance-null-provider.md) | Behavioral change | Preview 1 | -| [ConfigurationBinder throws for mismatched value](extensions/8.0/configurationbinder-exceptions.md) | Behavioral change | Preview 1 | -| [ConfigurationManager package no longer references System.Security.Permissions](extensions/8.0/configurationmanager-package.md) | Source incompatible | Preview 3 | -| [DirectoryServices package no longer references System.Security.Permissions](extensions/8.0/directoryservices-package.md) | Source incompatible | Preview 3 | -| [Empty keys added to dictionary by configuration binder](extensions/8.0/dictionary-configuration-binding.md) | Behavioral change | Preview 5 | -| [HostApplicationBuilderSettings.Args respected by HostApplicationBuilder ctor](extensions/8.0/hostapplicationbuilder-ctor.md) | Behavioral change | Preview 2 | -| [ManagementDateTimeConverter.ToDateTime returns a local time](extensions/8.0/dmtf-todatetime.md) | Behavioral change | RC 1 | +| Title | Type of change | +|-----------------------------------------------------------------------------------------------------------------------------------|-------------------| +| [ActivatorUtilities.CreateInstance behaves consistently](extensions/8.0/activatorutilities-createinstance-behavior.md) | Behavioral change | +| [ActivatorUtilities.CreateInstance requires non-null provider](extensions/8.0/activatorutilities-createinstance-null-provider.md) | Behavioral change | +| [ConfigurationBinder throws for mismatched value](extensions/8.0/configurationbinder-exceptions.md) | Behavioral change | +| [ConfigurationManager package no longer references System.Security.Permissions](extensions/8.0/configurationmanager-package.md) | Source incompatible | +| [DirectoryServices package no longer references System.Security.Permissions](extensions/8.0/directoryservices-package.md) | Source incompatible | +| [Empty keys added to dictionary by configuration binder](extensions/8.0/dictionary-configuration-binding.md) | Behavioral change | +| [HostApplicationBuilderSettings.Args respected by HostApplicationBuilder ctor](extensions/8.0/hostapplicationbuilder-ctor.md) | Behavioral change | +| [ManagementDateTimeConverter.ToDateTime returns a local time](extensions/8.0/dmtf-todatetime.md) | Behavioral change | +| [System.Formats.Cbor DateTimeOffset formatting change](extensions/8.0/cbor-datetime.md) | Behavioral change | ## Globalization diff --git a/docs/core/compatibility/extensions/8.0/cbor-datetime.md b/docs/core/compatibility/extensions/8.0/cbor-datetime.md new file mode 100644 index 0000000000000..6cf3c73d07168 --- /dev/null +++ b/docs/core/compatibility/extensions/8.0/cbor-datetime.md @@ -0,0 +1,94 @@ +--- +title: "Breaking change: System.Formats.Cbor DateTimeOffset formatting change" +description: Learn about the .NET 8 breaking change in .NET extensions where System.Formats.Cbor always formats and parses DateTimeOffset values using the invariant culture. +ms.date: 11/02/2023 +--- +# System.Formats.Cbor DateTimeOffset formatting change + +Since it was released in .NET 5, the System.Formats.Cbor NuGet package included built-in methods for serializing and deserializing DateTimeOffset values according to RFC 7049. Unfortunately, the implementations didn't use invariant culture when formatting and parsing DateTimeOffset values. This resulted in inconsistent or even incorrect date encodings on machines with cultures that use non-Gregorian calendars. + +The behavior has been changed so that invariant culture is always used when parsing and formatting DateTimeOffset values. This change might break your code if you relied on the previous behavior. Also, it might be impossible to read date values that were encoded with earlier versions of the System.Formats.Cbor NuGet package. + +## Version introduced + +.NET 8 + +## Previous behavior + +Consider this code that parses a DateTimeOffset value from a string and then encodes it using CBOR: + +```csharp +// Install a culture with a non-Gregorian calendar +var culture = new CultureInfo("he-IL"); +culture.DateTimeFormat.Calendar = new HebrewCalendar(); +Thread.CurrentThread.CurrentCulture = culture; + +DateTimeOffset value = DateTimeOffset.Parse("2020-04-09T14:31:21.3535941+01:00", CultureInfo.InvariantCulture); + +var writer = new CborWriter(); +writer.WriteDateTimeOffset(value); +byte[] cborEncoding = writer.Encode(); + +Console.WriteLine(Convert.ToHexString(cborEncoding)); +``` + +Previously, this code produced the following CBOR encoding: + +`C07828D7AAD7A922D7A42DD796272DD79822D7955431343A33313A32312E333533353934312B30313A3030` + +This encoding corresponds to `0(תש\"פ-ז'-ט\"וT14:31:21.3535941+01:00)` in CBOR diagnostic notation, which is an invalid date representation per RFC 7049. + +## New behavior + +Starting in .NET 8, the same code produces the following CBOR encoding: + +`C07821323032302D30342D30395431343A33313A32312E333533353934312B30313A3030` + +This encoding corresponds to `0("2020-04-09T14:31:21.3535941+01:00")` in CBOR diagnostic notation. + +## Type of breaking change + +This change is a [behavioral change](../../categories.md#behavioral-change). + +## Reason for change + +The previous behavior produced invalid date encodings per RFC 7049. + +## Recommended action + +You might have to be able to read CBOR date encodings that were persisted using earlier versions of System.Formats.Cbor if you don't upgrade to the latest version of the System.Formats.Cbor NuGet package. + +Alternatively, you can change your code to use the following extension method: + +```csharp +public static class CborReaderExtensions +{ + private const string Rfc3339FormatString = "yyyy-MM-ddTHH:mm:ss.FFFFFFFK"; + + public static DateTimeOffset ReadDateTimeOffsetReplacement(this CborReader reader, CultureInfo? cultureInfo = null) + { + CborTag tag = reader.PeekTag(); + if (tag != CborTag.DateTimeString) + { + throw new InvalidOperationException($"Expected CborTag {(int)CborTag.DateTimeString}"); + } + + reader.ReadTag(); + string dateString = reader.ReadTextString(); + return DateTimeOffset.ParseExact(dateString, Rfc3339FormatString, cultureInfo, DateTimeStyles. RoundtripKind); + } +} +``` + +Use this extension method to read a CBOR date encoding as follows: + +```csharp +var reader = new CborReader(cborEncoding); +DateTimeOffset date = reader.ReadDateTimeOffsetReplacement(culture); +Console.WriteLine(date.ToString(CultureInfo.InvariantCulture)); +``` + +## Affected APIs + +- +- diff --git a/docs/core/compatibility/toc.yml b/docs/core/compatibility/toc.yml index 48ce60e6cf94a..e0d1b08e0b4c7 100644 --- a/docs/core/compatibility/toc.yml +++ b/docs/core/compatibility/toc.yml @@ -102,6 +102,8 @@ items: href: extensions/8.0/hostapplicationbuilder-ctor.md - name: ManagementDateTimeConverter.ToDateTime returns a local time href: extensions/8.0/dmtf-todatetime.md + - name: System.Formats.Cbor DateTimeOffset formatting change + href: extensions/8.0/cbor-datetime.md - name: Globalization items: - name: Date and time converters honor culture argument @@ -1354,6 +1356,8 @@ items: href: extensions/8.0/hostapplicationbuilder-ctor.md - name: ManagementDateTimeConverter.ToDateTime returns a local time href: extensions/8.0/dmtf-todatetime.md + - name: System.Formats.Cbor DateTimeOffset formatting change + href: extensions/8.0/cbor-datetime.md - name: .NET 7 items: - name: Binding config to dictionary extends values