asp.net asp.net-mvc-3 datetime nodatime

asp.net - Conversiones de NodaTime(Parte 2). ¿Cómo?



asp.net-mvc-3 datetime (1)

Siguiendo mi primer post:

Conversiones de DateTime usando NodaTime en el sitio web ASP.Net MVC 3 Razor. ¿Cómo?

Estoy luchando para encontrar una manera fácil de convertir la fecha / hora entre local y UTC (en ambos sentidos), usando NodaTime.

La imagen actual es:

  • Tengo la fecha / hora guardada como UTC en la base de datos.
  • Al mostrarlo al usuario, debería considerar la zona horaria local y convertirla en consecuencia.
  • Cuando el usuario proporciona la fecha / hora como filtro, necesito volver a convertirlo a UTC antes de enviarlo a la consulta SQL.

Lo que tengo hasta ahora:

Extensión para convertir de UTC a local (esta parte funciona bien):

public static DateTime UTCtoLocal(this DateTime dateTime) { IDateTimeZoneProvider timeZoneProvider = DateTimeZoneProviders.Tzdb; var utcTimeZone = timeZoneProvider["UTC"]; var dateTimeFromDb = new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, dateTime.Hour, dateTime.Minute, dateTime.Second, dateTime.Millisecond); var zonedDbDateTime = utcTimeZone.AtLeniently(LocalDateTime.FromDateTime(dateTimeFromDb)); var usersTimezoneId = "Europe/London"; //just an example var usersTimezone = timeZoneProvider[usersTimezoneId]; var usersZonedDateTime = zonedDbDateTime.WithZone(usersTimezone); return usersZonedDateTime.ToDateTimeUnspecified(); }

Extensión para convertir de local a UTC (esta parte es el problema):

public static DateTime LocaltoUTC(this DateTime dateTime) { IDateTimeZoneProvider timeZoneProvider = DateTimeZoneProviders.Tzdb; var usersTimezoneId = "Europe/London"; var usersTimezone = timeZoneProvider[usersTimezoneId]; var dateTimeFromDb = new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, dateTime.Hour, dateTime.Minute, dateTime.Second, dateTime.Millisecond); var zonedDbDateTime = usersTimezone.AtLeniently(LocalDateTime.FromDateTime(dateTimeFromDb)); var utcTimezoneId = "UTC"; var utcTimezone = timeZoneProvider[utcTimezoneId]; var utcZonedDateTime = zonedDbDateTime.WithZone(utcTimezone); return utcZonedDateTime.ToDateTimeUtc(); }

¿Qué estoy haciendo mal aquí?


Su UTCToLocal parece que está haciendo más trabajo del que necesita, para ser honesto.

Simplemente debería ser:

// Note: the DateTime here must have a "Kind" of Utc. public static DateTime UTCtoLocal(this DateTime dateTime) { Instant instant = Instant.FromDateTimeUtc(dateTime); IDateTimeZoneProvider timeZoneProvider = DateTimeZoneProviders.Tzdb; var usersTimezoneId = "Europe/London"; //just an example var usersTimezone = timeZoneProvider[usersTimezoneId]; var usersZonedDateTime = instant.InZone(usersTimezone); return usersZonedDateTime.ToDateTimeUnspecified(); }

Del mismo modo, su LocalToUTC debe estar en esta línea:

// The DateTime here should have a "Kind" of Unspecified public static DateTime LocaltoUTC(this DateTime dateTime) { LocalDateTime localDateTime = LocalDateTime.FromDateTime(dateTime); IDateTimeZoneProvider timeZoneProvider = DateTimeZoneProviders.Tzdb; var usersTimezoneId = "Europe/London"; var usersTimezone = timeZoneProvider[usersTimezoneId]; var zonedDbDateTime = usersTimezone.AtLeniently(localDateTime); return zonedDbDateTime.ToDateTimeUtc(); }

No es necesario convertirlo a una zona horaria diferente: ZonedDateTime sabe qué es el instante, y ToDateTimeUtc hará lo correcto. Tenga en cuenta que no hay un dateTimeFromDb real aquí, porque si está convirtiendo desde un DateTime no especificado, es probable que sea del usuario ...