Ti manca un punto critico: A DateTime
il cui tipo è Local
non rappresenta sempre un momento unico nel tempo. Questo è il motivo per cui non esiste alcuna mappatura diretta a Instant
.
Durante una transizione DST fall-back, un locale DateTime
può rappresentare uno dei due possibili momenti nel tempo. Se hai intenzione di convertirlo in un Instant
, allora da qualche parte devi decidere quale momento devi scegliere.
Nella risposta che hai dato, sto assumendo si è ottenuto il timezone
da uno dei seguenti modi:
var timezone = DateTimeZoneProviders.Tzdb.GetSystemDefault();
o
var timezone = DateTimeZoneProviders.Bcl.GetSystemDefault();
entrambi sono ok per questo compito. Poi il codice che ha dato:
var localTime = LocalDateTime.FromDateTime(time);
var zonedTime = localTime.InZoneStrictly(timeZone);
return zonedTime.ToInstant();
Questo è esattamente corretto, ma dal momento che è stato utilizzato InZoneStrictly
, si otterrà un AmbiguousTimeException
durante la transizione di ripiego.
È possibile evitare questo utilizzando InZoneLeniently
, che sceglierà l'ultima delle due possibilità (in genere il tempo "Standard"). Ma ancora più importante, è possibile utilizzare InZone
e fornire uno standard resolver personalizzato per controllare il comportamento in modo più preciso.
Per quanto riguarda il suo approccio originale:
Instant.FromDateTimeUtc(time.ToUniversalTime())
Questo è ok e non corromperà i dati, ma capire che si baserà sul comportamento del BCL di locali alla conversione universale. È identico a InZoneLeniently
, in quanto un valore ambiguo verrà considerato come il tempo "standard".
Questo è un ottimo esempio di come NodaTime offre un'API più precisa. Invece di fare supposizioni, hai l'opportunità di essere specifico e di fornire un comportamento personalizzato. Alla fine hai ottenuto lo stesso risultato, ma ha portato questo problema in primo piano invece di nasconderlo.
Grazie per aver dedicato del tempo per spiegare questo. Penso che questo sarà utile per le altre persone che sono nuove nella biblioteca. – Sam