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 ...