Obtener el LocalDateTime del sistema en Noda Time
Pregunta
¿Cuál es la forma idiomática de obtener el tiempo del sistema como LocalDateTime
en tiempo de Noda?El método más directo que se me ocurre sería
var dt = DateTime.Now
LocalDateTime systemTime = new LocalDateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute);
pero dado que Noda Time Todo el propósito es reemplazar DateTime con algo que tenga una semántica más agradable., asumí que había un método preferido que usar DateTime
de la manera anterior.Lo mejor que se me ocurrió usando las instalaciones de Noda es
var zone = NodaTime.TimeZones.BclDateTimeZone.ForSystemDefault();
LocalDateTime systemTime = SystemClock.Instance.Now.InZone(zone).LocalDateTime;
pero esto parece bastante detallado.
Solución
Su segundo ejemplo es exactamente cómo haría esto.Es intencionalmente verboso.Ver La filosofía de diseño de Noda Time.
Piénselo en tres partes:
Obtenga el momento actual en el tiempo:
// Instant now = SystemClock.Instance.Now; // NodaTime 1.x Instant now = SystemClock.Instance.GetCurrentInstant(); // NodaTime 2.x
Obtenga la zona horaria del sistema.(Esta es la sintaxis preferida)
DateTimeZone tz = DateTimeZoneProviders.Bcl.GetSystemDefault();
Aplicar la zona horaria al instante:
ZonedDateTime zdt = now.InZone(tz);
Su último paso para obtener un LocalDateTime
es trivial, pero reconoce que cuando lo haces, estás eliminando cualquier información de zona horaria."Local" en NodaTime sí no significa "local para la computadora donde se ejecuta el código".(En otras palabras, no es como DateTimeKind.Local
)
Cosas adicionales en las que pensar:
Quizás prefieras abstraer el reloj usando el
IClock
interfaz:IClock clock = SystemClock.Instance; // Instant now = clock.Now; // NodaTime 1.x Instant now = clock.GetCurrentInstant(); // NodaTime 2.x
Luego, podría pasar el reloj como parámetro del método o inyectarlo con su marco DI/IoC favorito.(Autofac, Ninject, StructureMap, lo que sea...).La ventaja es que entonces podrías usar un
NodaTime.Testing.FakeClock
durante las pruebas unitarias.Ver Pruebas unitarias con Noda Time para más detalles.Quizás también prefieras pasar por el
DateTimeZone
para que pueda ejecutar su código en cualquier lugar sin estar vinculado a la zona horaria del sistema.Esto es importante para las aplicaciones de servidor, pero no tanto para las aplicaciones de escritorio/móviles.Si tiene otro trabajo que utiliza zonas horarias de la IANA, o si está utilizando la compilación .NET Standard de Noda Time, cambie el paso 2 para usar la
Tzdb
proveedor:DateTimeZone tz = DateTimeZoneProviders.Tzdb.GetSystemDefault();
Las zonas TZDB son mucho más precisas que las zonas BCL.Noda Time asignará la zona horaria de Windows (BCL) de su sistema a una zona horaria de IANA (TZDB) en esta llamada inicial.
Si tienes curiosidad sobre por qué DateTime.Now
es tan compacto mientras que Noda Time es tan detallado, intente descompilar DateTime.Now
o consultar las fuentes de referencia de MS.Verás que realiza esencialmente los mismos pasos debajo del capó.