2013-05-21 6 views
15

Nach meinem ersten Beitrag:NodaTime Konvertierungen (Teil 2). Wie man?

DateTime conversions using NodaTime on ASP.Net MVC 3 Razor website. How to?

Ich kämpfe einen einfachen Weg zu finden, Datum/Uhrzeit zwischen lokalen und UTC (beide Richtungen), mit NodaTime zu konvertieren.

Das aktuelle Bild ist:

  • Ich habe das Datum/Uhrzeit als UTC in der Datenbank gespeichert.
  • Wenn ich es dem Benutzer zeige, sollte ich die lokale Zeitzone berücksichtigen und sie entsprechend konvertieren.
  • Wenn der Benutzer Datum/Uhrzeit als Filter bereitstellt, muss ich ihn vor dem Senden an die SQL-Abfrage zurück in UTC konvertieren.

Was ich habe, so weit:

Erweiterung von UTC in lokalen zu konvertieren (dieser Teil funktioniert gut):

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(); 
    } 

Erweiterung von lokalen zu konvertieren zurück zu UTC (diese Teil ist das Problem):

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(); 
    } 

Was mache ich hier falsch?

Antwort

26

Ihr UTCToLocal sieht aus, als ob es mehr Arbeit leistet, als es braucht, um ehrlich zu sein.

Es sollte einfach sein:

// 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(); 
} 

Sie brauchen nicht, es zu einer anderen Zeitzone zu konvertieren:

// 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(); 
} 

Ähnlich Ihre LocalToUTC entlang dieser Linien sollte ZonedDateTime weiß, was die Instant ist, und ToDateTimeUtc wird das Richtige tun. Beachten Sie, dass es hier keine echte dateTimeFromDb gibt, denn wenn Sie von einer nicht spezifizierten DateTime konvertieren, ist das vermutlich vom Benutzer ...

+0

Nochmals vielen Dank, @Jon. Werde das hier ausprobieren. Bleib dran bei der guten Arbeit an NodaTime. – melancia

+0

Was ist die Verwendung von LocaltoUTC, sollte nicht DateTime.ToUniversalTime() gut funktionieren? danke – pajics

+2

@pajics: Nein, weil das immer die Systemzeitzone benutzt - das OP möchte die Zeitzone des Benutzers benutzen. –