2009-07-10 5 views
8

Ich benutze DateTime.Now um etwas nach dem heutigen Datum zu zeigen, und wenn ich lokal arbeite (Malta, Europa) erscheinen die Zeiten korrekt (offensichtlich wegen der Zeitzone) aber Natürlich, wenn ich es auf meinen Hosting-Server (USA) hochlade, entspricht DateTime.Now nicht der richtigen Zeitzone.C#: Sicherstellen, dass DateTime.Now eine GMT + 1 Zeit zurückgibt

Daher in meinem Code Wie kann ich DateTime.Now konvertieren, um die Zeit von einer GMT + 1 Zeitzone korrekt zurückzugeben?

Antwort

14

Verwenden Sie die Timezone Klasse im System gefunden .Ader;

Sie müssen das DateTimeKind für DateTimeKind.Utc dafür festlegen.

DateTime MyTime = new DateTime(1990, 12, 02, 19, 31, 30, DateTimeKind.Utc); 

DateTime MyTimeInWesternEurope = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(MyTime, "W. Europe Standard Time"); 

Nur wenn Sie .Net 3.5 verwenden, obwohl!

4

Ich glaube nicht, dass Sie in Ihrem Code eine Eigenschaft festlegen können, die DateTime.Now etwas anderes als die aktuelle Uhrzeit des Computers zurückgibt, auf dem der Code ausgeführt wird. Wenn Sie eine Möglichkeit haben wollen, immer eine andere Zeit zu bekommen, müssen Sie wahrscheinlich eine andere Funktion einfügen. Sie können die Hin- und Rückfahrt über UTC tun und fügen Sie die gewünschte Offset:

private static DateTime GetMyTime() 
{ 
    return DateTime.UtcNow.AddHours(1); 
} 

(Codebeispiel nach Lukes Kommentar über das Innenleben von DateTime.Now aktualisiert)

+0

Mit 'DateTime.UtcNow.AddHours (1)' stattdessen werden Sie sparen etwas tippen! – LukeH

+0

Ja, das habe ich gemerkt. Aber ich bin mir nicht sicher, ob sie genau dasselbe tun; UtcNow holt die Systemzeit und führt einige Operationen mit "magischen Zahlen" aus, während ToUniversalTime die TimeZone.CurrentTimeZone verwendet, um die Utc-Zeit zu erhalten. Ich nehme an, dass sie immer die gleiche Zeit zurückgeben werden; o) –

+0

'DateTime.Now' verwendet' UtcNow' hinter den Kulissen, so wird Ihr ursprünglicher Code in etwas wie 'DateTime.UtcNow.ToLocalTime() übersetzt. ToUniversalTime(). AddHours (1) '. – LukeH

14

Es hängt davon ab, was Sie mit "einer GMT + 1 Zeitzone" meinen. Meinst du permanent UTC + 1, oder meinst du UTC + 1 oder UTC + 2 abhängig von DST?

Wenn Sie .NET 3.5, verwenden TimeZoneInfo zu erhalten eine entsprechende Zeitzone verwenden, dann verwenden:

// Store this statically somewhere 
TimeZoneInfo maltaTimeZone = TimeZoneInfo.FindSystemTimeZoneById("..."); 
DateTime utc = DateTime.UtcNow; 
DateTime malta = TimeZoneInfo.ConvertTimeFromUtc(utc, maltaTimeZone); 

Sie müssen die System-ID für die Malta Zeitzone trainieren, aber Sie kann man erkennen, lokal, indem Sie diesen Code einfach tun:

Console.WriteLine(TimeZoneInfo.Local.Id); 

durch Ihre Kommentare zu urteilen, wird dieses Bit irrelevant sein, aber nur für andere ...

Wenn Sie nicht mit .NET 3.5 verwenden, müssen Sie die Sommerzeit selbst berechnen. Um ehrlich zu sein, die einfachste Möglichkeit, das zu tun, wird eine einfache Nachschlagetabelle sein. Berechnen Sie die DST-Änderungen für die nächsten Jahre, und schreiben Sie dann eine einfache Methode, um den Offset zu einer bestimmten UTC-Zeit zurückzugeben, wobei diese Liste fest codiert ist. Sie könnten nur eine sortierte List<DateTime> mit den bekannten Änderungen und wechseln zwischen 1 und 2 Stunden wollen, bis Sie das Datum nach der letzten Änderung ist:

// Be very careful when building this list, and make sure they're UTC times! 
private static readonly IEnumerable<DateTime> DstChanges = ...; 

static DateTime ConvertToLocalTime(DateTime utc) 
{ 
    int hours = 1; // Or 2, depending on the first entry in your list 
    foreach (DateTime dstChange in DstChanges) 
    { 
     if (utc < dstChange) 
     { 
      return DateTime.SpecifyKind(utc.AddHours(hours), DateTimeKind.Local); 
     } 
     hours = 3 - hours; // Alternate between 1 and 2 
    } 
    throw new ArgumentOutOfRangeException("I don't have enough DST data!"); 
} 
+0

Jon, Ich habe deine Antwort bearbeitet, um die Parameter von TimeZoneInfo.ConvertTimeFromUtc zu invertieren –

+0

Whoops, danke. Das Seltsame ist, dass ich sie zuerst überprüft habe - dann habe ich sie sowieso in die falsche Richtung gesehen! –

+0

Ihre Lösung löst diese Ausnahme in der ConvertTimeFromUtc-Methode aus: Die Konvertierung konnte nicht abgeschlossen werden, da für die angegebene DateTime die Kind-Eigenschaft nicht korrekt festgelegt wurde. Wenn die Kind-Eigenschaft beispielsweise DateTimeKind.Local ist, muss die Quellzeitzone TimeZoneInfo.Local lauten. Parametername: sourceTimeZone –

Verwandte Themen