2016-06-06 13 views
1

Wir behalten alle Zeiten in unserer Datenbank als UTC. mit .net FunktionKonvertierung von UTC in Zeitzone Zeit produziert anderes Ergebnis mit 4.0 und 3.5 SP1

public static DateTime ConvertToLocalTime(DateTime utcTime, string timezoneId) 
{ 
     try 
     { 
      return TimeZoneInfo.ConvertTimeBySystemTimeZoneId(utcTime, TimeZoneInfo.Utc.StandardName, timezoneId); 
     } 
     catch 
     { 
      return new DateTime(); 
     } 
} 

Es gab ein Problem gemeldet Basierend auf den Standort des Kunden wird die UTC-Zeit in einer lokalen Zeit konvertiert, dass einige Berichte falsche Ergebnisse in Datetime-Feldern produziert haben, und wenn ich es tiefer begann suchen, Ich erkannte, dass der oben genannte Code namens SQL2008 (kompiliert mit .net 3.5) ein anderes Ergebnis erzeugt, wenn er von der mit .NET 4.0 kompilierten Client-Anwendung aufgerufen wird. Das Ergebnis ist in 3.5 falsch und in 4.0 für Chile Zeitzone für Jahr 2015 korrekt, wenn DST das ganze Jahr beobachtet wurde.

Ich kann davon ausgehen, dass dies möglicherweise ein Hotfix fehlgeschlagen speziell für .net 3.5 hergestellt wurde und derzeit fehlt. Aber wenn jemand früher auf dieses oder ein ähnliches Problem gestoßen ist, würde ich mich über zusätzliche Informationen freuen. erste

Antwort

1

Ein paar Dinge:

  • nicht StandardName Verwenden Sie, wenn Sie Id bedeuten. Während sie in einigen Fällen übereinstimmen können, ist das nicht garantiert. Bedenken Sie insbesondere, dass StandardName (zusammen mit DaylightName und DisplayName) basierend auf der Hauptsprache des Betriebssystems lokalisiert sind. Sie werden auf einem japanischen PC anders aussehen als auf einem englischen.

  • Die Id für UTC ist einfach "UTC" - so könnten Sie das hart codieren, wenn Sie möchten. Verwenden Sie alternativ TimeZoneInfo.Utc.Id, oder wechseln Sie vorzugsweise zu der TimeZoneInfo.ConvertTimeFromUtc Methode.

  • Der Versuch/Fang hier wird alle echten Ausnahmen maskieren, wie TimeZoneNotFoundException, wenn die timeZoneId nicht gültig ist.

nun im Hinblick auf die Unterschiede zwischen den Versionen, das Verhalten Sie erleben ist das in KB3012229 beschrieben. Während der Artikel russische Zeitzonen erwähnt, gilt dies auch für die jüngsten Zeitzonenänderungen in Chile. Es tritt auf, weil die Klasse TimeZoneInfo.AdjustmentRule ursprünglich entworfen wurde, ohne zu berücksichtigen, dass sich der Basisoffset von UTC auch von Jahr zu Jahr ändern kann. Dies wurde in .NET 4.6 behoben, indem eine interne Eigenschaft BaseUtcOffsetDelta hinzugefügt wurde, die you can see in the reference sources here.

Wenn .NET 4.6 oder höher auf dem Computer installiert ist, hat jede Anwendung, die die .NET 4-Laufzeit verwendet (dh jede App, die auf .NET 4.0 oder höher abzielt), die korrigierte Implementierung und funktioniert ordnungsgemäß. (Dies ist auch in .NET Core behoben.)

Vom Testen auf meiner eigenen Maschine, scheint es auch in .NET 3.5 behoben werden, aber ich bin mir nicht sicher, welches spezielle Update das Problem gelöst. Stellen Sie sicher, dass Sie alle Updates installiert haben, und das Problem sollte (wahrscheinlich) verschwinden.

Some more on this here.

+0

Danke, dass Sie auf einen Fehler im Code und die detaillierten Hintergrundinformationen hingewiesen haben. Die Verwendung von StandardName ist definitiv falsch. Ich werde die Updates versuchen und hoffentlich den fehlenden fangen. – peregrinus