Cambio de formato System.Formats.Cbor DateTimeOffset

Desde que se publicó en .NET 5, el paquete NuGet System.Formats.Cbor incluía métodos integrados para serializar y deserializar valores DateTimeOffset según RFC 7049. Desafortunadamente, las implementaciones no usaron la referencia cultural invariable al aplicar formato a los valores DateTimeOffset y analizarlos. Esto dio lugar a codificaciones de fecha incoherentes o incluso incorrectas en máquinas con referencias culturales que usan calendarios no gregorianos.

El comportamiento se ha cambiado para que siempre se use la referencia cultural invariable al analizar y dar formato a los valores DateTimeOffset. Este cambio podría interrumpir el código si se basaba en el comportamiento anterior. Además, podría ser imposible leer valores de fecha codificados con versiones anteriores del paquete NuGet System.Formats.Cbor.

Versión introducida

.NET 8

Comportamiento anterior

Tenga en cuenta este código que analiza un valor DateTimeOffset de una cadena y, a continuación, lo codifica mediante 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, este código producía la siguiente codificación CBOR:

C07828D7AAD7A922D7A42DD796272DD79822D7955431343A33313A32312E333533353934312B30313A3030

Esta codificación corresponde a 0(תש\"פ-ז'-ט\"וT14:31:21.3535941+01:00) en notación de diagnóstico de CBOR, que es una representación de fecha no válida por RFC 7049.

Comportamiento nuevo

A partir de .NET 8, el mismo código genera la siguiente codificación CBOR:

C07821323032302D30342D30395431343A33313A32312E333533353934312B30313A3030

Esta codificación corresponde a 0("2020-04-09T14:31:21.3535941+01:00") en notación de diagnóstico de CBOR.

Tipo de cambio importante

Este es un cambio de comportamiento.

Motivo del cambio

El comportamiento anterior produjo codificaciones de fecha no válidas por RFC 7049.

Es posible que tenga que leer las codificaciones de fecha de CBOR que se conservaron con versiones anteriores de System.Formats.Cbor si no actualiza a la versión más reciente del paquete NuGet System.Formats.Cbor.

Como alternativa, puede cambiar el código para usar el siguiente método de extensión:

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 este método de extensión para leer una codificación de fecha de CBOR como se indica a continuación:

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

API afectadas