Quello che voglio ottenere è convertire un DateTime (analizzato da una stringa assunta in EST/EDT) in UTC. Sto usando NodaTime perché ho bisogno di usare i fusi orari Olson.Utilizzo di NodaTime per convertire i valori datetime non validi (saltati) in UTC
Conversione di un DateTime non valido (ignorato) in UTC utilizzando ZonePlocalMappingResolver di NodaTime non converte la parte minuti e secondi dell'input perché ho configurato CustomResolver per restituire l'inizio dell'intervallo dopo il divario. NodaTime non sembra avere un equivalente di TimeZoneInfo.IsInvalidTime.
Come utilizzare NodaTime per convertire i valori datetime saltati in UTC e far corrispondere il risultato del metodo GetUtc() nella classe Utils di seguito? (Metodo Utils.GetUtc utilizza System.TimeZoneInfo non NodaTime)
Questo è il banco di prova:
[TestMethod]
public void Test_Invalid_Date()
{
var ts = new DateTime(2013, 3, 10, 2, 15, 45);
// Convert to UTC using System.TimeZoneInfo
var utc = Utils.GetUtc(ts).ToString(Utils.Format);
// Convert to UTC using NodaTime (Tzdb/Olson dataabase)
var utcNodaTime = Utils.GetUtcTz(ts).ToString(Utils.Format);
Assert.AreEqual(utc, utcNodaTime);
}
Questo è quello che sto ottenendo:
Assert.AreEqual fallito. Previsto: < 2013-03-10 07: 15: 45.000000>. Effettivo: < 2013-03-10 07: 00: 00.000000>.
Ecco la classe Utils (anche su github):
using System;
using NodaTime;
using NodaTime.TimeZones;
/// <summary>
/// Functions to Convert To and From UTC
/// </summary>
public class Utils
{
/// <summary>
/// The date format for display/compare
/// </summary>
public const string Format = "yyyy-MM-dd HH:mm:ss.ffffff";
/// <summary>
/// The eastern U.S. time zone
/// </summary>
private static readonly NodaTime.DateTimeZone BclEast = NodaTime.DateTimeZoneProviders.Bcl.GetZoneOrNull("Eastern Standard Time");
private static readonly TimeZoneInfo EasternTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
private static readonly NodaTime.DateTimeZone TzEast = NodaTime.DateTimeZoneProviders.Tzdb.GetZoneOrNull("America/New_York");
private static readonly ZoneLocalMappingResolver CustomResolver = Resolvers.CreateMappingResolver(Resolvers.ReturnLater, Resolvers.ReturnStartOfIntervalAfter);
public static DateTime GetUtc(DateTime ts)
{
return TimeZoneInfo.ConvertTimeToUtc(EasternTimeZone.IsInvalidTime(ts) ? ts.AddHours(1.0) : ts, EasternTimeZone);
}
public static DateTime GetUtcTz(DateTime ts)
{
var local = LocalDateTime.FromDateTime(ts);
var zdt = TzEast.ResolveLocal(local, CustomResolver);
return zdt.ToDateTimeUtc();
}
public static DateTime GetUtcBcl(DateTime ts)
{
var local = LocalDateTime.FromDateTime(ts);
var zdt = BclEast.ResolveLocal(local, CustomResolver);
return zdt.ToDateTimeUtc();
}
}
Ho aggiornato i collegamenti di riferimento in questa risposta per portare alla documentazione dell'API più recente ospitata su nodatime.org anziché sul vecchio sito mancante di codice google. – clarkitect