Dela via


Ändring i formateringen för System.Formats.Cbor DateTimeOffset

Eftersom det släpptes i .NET 5 innehöll NuGet-paketet System.Formats.Cbor inbyggda metoder för serialisering och deserialisering av DateTimeOffset-värden enligt RFC 7049. Implementeringarna använde tyvärr inte invariant kultur vid formatering och parsning av DateTimeOffset-värden. Detta resulterade i inkonsekventa eller till och med felaktiga datumkodningar på datorer med kulturer som använder icke-gregorianska kalendrar.

Beteendet har ändrats så att invariant kultur alltid används vid parsning och formatering av DateTimeOffset-värden. Den här ändringen kan bryta koden om du förlitade dig på det tidigare beteendet. Det kan också vara omöjligt att läsa datumvärden som kodades med tidigare versioner av NuGet-paketet System.Formats.Cbor.

Version lanserad

.NET 8

Tidigare beteende

Tänk på den här koden som parsar ett DateTimeOffset-värde från en sträng och sedan kodar den med CBOR:

// 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));

Tidigare skapade den här koden följande CBOR-kodning:

C07828D7AAD7A922D7A42DD796272DD79822D7955431343A33313A32312E333533353934312B30313A3030

Den här kodningen motsvarar 0(תש\"פ-ז'-ט\"וT14:31:21.3535941+01:00) i CBOR-diagnostiknotation, vilket är en ogiltig datumrepresentation enligt RFC 7049.

Nytt beteende

Från och med .NET 8 genererar samma kod följande CBOR-kodning:

C07821323032302D30342D30395431343A33313A32312E333533353934312B30313A3030

Den här kodningen motsvarar 0("2020-04-09T14:31:21.3535941+01:00") i CBOR-diagnostisk notation.

Typ av brytande ändring

Den här ändringen är en beteendeförändring.

Orsak till ändring

Det tidigare beteendet skapade ogiltiga datumkodningar per RFC 7049.

Du kanske måste kunna läsa CBOR-datumkodningar som har sparats med tidigare versioner av System.Formats.Cbor om du inte uppgraderar till den senaste versionen av NuGet-paketet System.Formats.Cbor.

Du kan också ändra koden så att den använder följande tilläggsmetod:

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);
    }
}

Använd den här tilläggsmetoden för att läsa en CBOR-datumkodning enligt följande:

var reader = new CborReader(cborEncoding);
DateTimeOffset date = reader.ReadDateTimeOffsetReplacement(culture);
Console.WriteLine(date.ToString(CultureInfo.InvariantCulture));

Berörda API:er