Alteração de formatação de System.Formats.Cbor DateTimeOffset

Desde que foi lançado no .NET 5, o pacote NuGet System.Formats.Cbor incluiu métodos internos para serializar e desserializar valores DateTimeOffset de acordo com a RFC 7049. Entretanto, as implementações não usavam cultura invariável ao formatar e analisar valores DateTimeOffset. Isso resultou em codificações de datas inconsistentes ou mesmo incorretas em computadores com culturas que usam calendários não gregorianos.

O comportamento foi alterado para que a cultura invariável seja sempre usada ao analisar e formatar valores DateTimeOffset. Essa alteração poderá interromper seu código se você dependia do comportamento anterior. Além disso, poderá ser impossível ler valores de data que foram codificados com versões anteriores do pacote NuGet System.Formats.Cbor.

Versão introduzida

.NET 8

Comportamento anterior

Considere este código que analisa um valor DateTimeOffset em uma cadeia de caracteres e, em seguida, codifica-o usando 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));

Anteriormente, esse código produzia a seguinte codificação CBOR:

C07828D7AAD7A922D7A42DD796272DD79822D7955431343A33313A32312E333533353934312B30313A3030

Essa codificação corresponde a 0(תש\"פ-ז'-ט\"וT14:31:21.3535941+01:00) na notação de diagnóstico CBOR, que é uma representação de data inválida de acordo com a RFC 7049.

Novo comportamento

A partir do .NET 8, o mesmo código produz a seguinte codificação CBOR:

C07821323032302D30342D30395431343A33313A32312E333533353934312B30313A3030

Essa codificação corresponde a 0("2020-04-09T14:31:21.3535941+01:00") na notação diagnóstica do CBOR.

Tipo de alteração interruptiva

Esta é uma alteração comportamental.

Motivo da alteração

O comportamento anterior produzia codificações de data inválidas de acordo com a RFC 7049.

Talvez seja necessário ler codificações de data CBOR que foram mantidas usando versões anteriores do System.Formats.Cbor se você não atualizar para a versão mais recente do pacote NuGet System.Formats.Cbor.

Como alternativa, altere seu código para usar o seguinte método de extensão:

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 esse método de extensão para ler uma codificação de data CBOR da seguinte maneira:

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

APIs afetadas