Condividi tramite


Modifica della formattazione di System.Formats.Cbor DateTimeOffset

Poiché è stato rilasciato in .NET 5, il pacchetto NuGet System.Formats.Cbor includeva metodi predefiniti per serializzare e deserializzare i valori DateTimeOffset in base a RFC 7049. Sfortunatamente, le implementazioni non utilizzavano impostazioni cultura inglese non dipendenti da Paese/area geografica durante la formattazione e l'analisi dei valori DateTimeOffset. Ciò ha comportato codifiche di data incoerenti o persino non corrette nei computer con impostazioni cultura che utilizzano calendari non gregoriani.

Il comportamento è stato modificato in modo che le impostazioni cultura inglese non dipendenti da Paese/area geografica vengano sempre usate durante l'analisi e la formattazione dei valori DateTimeOffset. Tale modifica potrebbe interrompere il codice se ci si è basati sul comportamento precedente. Inoltre, potrebbe essere impossibile leggere i valori di data codificati con le versioni precedenti del pacchetto NuGet System.Formats.Cbor.

Versione introdotta

.NET 8

Comportamento precedente

Si consideri questo codice che analizza un valore DateTimeOffset da una stringa e quindi lo codifica 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));

In precedenza, questo codice produceva la codifica CBOR seguente:

C07828D7AAD7A922D7A42DD796272DD79822D7955431343A33313A32312E333533353934312B30313A3030

questa codifica corrisponde a 0(תש\"פ-ז'-ט\"וT14:31:21.3535941+01:00) nella notazione diagnostica CBOR, ovvero una rappresentazione di data non valida per RFC 7049.

Nuovo comportamento

A partire da .NET 8, lo stesso codice produce la codifica CBOR seguente:

C07821323032302D30342D30395431343A33313A32312E333533353934312B30313A3030

Questa codifica corrisponde a 0("2020-04-09T14:31:21.3535941+01:00") nella notazione diagnostica CBOR.

Tipo di modifica che causa un'interruzione

Questa è una modifica funzionale.

Motivo della modifica

Il comportamento precedente ha prodotto codifiche di data non valide per RFC 7049.

Potrebbe essere necessario leggere le codifiche di data CBOR persistenti usando le versioni precedenti di System.Formats.Cbor se non si esegue l'aggiornamento alla versione più recente del pacchetto NuGet System.Formats.Cbor.

In alternativa, è possibile modificare il codice in modo da usare il metodo di estensione seguente:

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

usare questo metodo di estensione per leggere una codifica data CBOR come indicato di seguito:

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

API interessate