Sdílet prostřednictvím


Změna formátování System.Formats.Cbor DateTimeOffset

Vzhledem k tomu, že byl vydán v rozhraní .NET 5, balíček NuGet System.Formats.Cbor obsahoval integrované metody pro serializaci a deserializaci hodnot DateTimeOffset podle RFC 7049. Implementace bohužel při formátování a analýze hodnot DateTimeOffset nepoužíly neutrální jazykovou verzi. Výsledkem je nekonzistentní nebo dokonce nesprávné kódování kalendářních dat na počítačích s jazykovými verzemi, které používají negregoriánské kalendáře.

Chování bylo změněno tak, aby se při analýze a formátování hodnot DateTimeOffset vždy používala invariantní jazyková verze. Tato změna může poškodit kód, pokud jste se spoléhali na předchozí chování. Také může být nemožné číst hodnoty kalendářních dat, které byly zakódovány pomocí dřívějších verzí balíčku System.Formats.Cbor NuGet.

Zavedená verze

.NET 8

Předchozí chování

Vezměte v úvahu tento kód, který parsuje hodnotu DateTimeOffset z řetězce a pak ho kóduje pomocí 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));

Dříve tento kód vytvořil následující kódování CBOR:

C07828D7AAD7A922D7A42DD796272DD79822D7955431343A33313A32312E333533353934312B30313A3030

Toto kódování odpovídá 0(תש\"פ-ז'-ט\"וT14:31:21.3535941+01:00) diagnostickému zápisu CBOR, což je neplatné vyjádření data na RFC 7049.

Nové chování

Počínaje rozhraním .NET 8 vytvoří stejný kód následující kódování CBOR:

C07821323032302D30342D30395431343A33313A32312E333533353934312B30313A3030

Toto kódování odpovídá 0("2020-04-09T14:31:21.3535941+01:00") diagnostickému zápisu CBOR.

Typ zásadní změny

Tato změna je změna chování.

Důvod změny

Předchozí chování vytvořilo neplatné kódování kalendářních dat na RFC 7049.

Pokud neupgradujete na nejnovější verzi balíčku NuGet System.Formats.Cbor, budete možná muset přečíst kódování data CBOR, která byla zachována pomocí starších verzí souboru System.Formats.Cbor.

Případně můžete změnit kód tak, aby používal následující metodu rozšíření:

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

Tuto metodu rozšíření použijte ke čtení kódování data CBOR následujícím způsobem:

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

Ovlivněná rozhraní API