2009-07-10 9 views
8

Sto usando DateTime.Now per mostrare qualcosa in base alla data odierna, e quando si lavora localmente (Malta, Europa) le ore appaiono correttamente (ovviamente a causa del fuso orario) ma naturalmente quando lo carico sul mio server di hosting (USA), DateTime.Now non rappresenta il fuso orario corretto.C#: Assicurarsi che DateTime.Now restituisca una GMT + 1 ora

Pertanto, nel mio codice, come posso convertire DateTime.Now di tornare correttamente il tempo da un fuso orario GMT + 1?

risposta

14

Utilizzare la classe TimeZoneInfo trovato nel sistema .Nucleo;

è necessario impostare il DateTimeKind a DateTimeKind.Utc per questo.

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

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

Solo se si utilizza .Net 3.5 però!

4

Non credo che si può impostare una proprietà nel codice che farà tornare DateTime.Now altro che l'ora corrente del computer in cui il codice viene eseguito. Se vuoi avere un modo per ottenere sempre un altro tempo, probabilmente avrai bisogno di ricomporre un'altra funzione. Si può può fare il round-trip over UTC e aggiungere l'offset desiderato:

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

(esempio di codice aggiornato dopo il commento di Luca sul funzionamento interno di DateTime.Now)

+0

Usando 'DateTime.UtcNow.AddHours (1)' invece vi farà risparmiare un po 'di battitura! – LukeH

+0

Sì, l'ho capito. Ma poi non sono sicuro che facciano esattamente la stessa cosa; UtcNow recupera l'ora del sistema e esegue alcune operazioni con "numeri magici", mentre ToUniversalTime utilizza TimeZone.CurrentTimeZone per ottenere l'ora Utc. Suppongo che sarà sempre tornare nello stesso tempo però;. O) –

+0

'' DateTime.Now' utilizza UtcNow' dietro le quinte, in modo che il codice originale si traduce in qualcosa di simile a 'DateTime.UtcNow.ToLocalTime() ToUniversalTime() AddHours (. 1) '. – LukeH

14

Dipende da cosa si intende per "un GMT + 1 fuso orario". Intendi in modo permanente UTC + 1 o intendi UTC + 1 o UTC + 2 a seconda dell'ora legale?

Se si sta utilizzando .NET 3.5, utilizzare TimeZoneInfo per ottenere un fuso orario appropriato, quindi utilizzare:

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

Avrete bisogno di elaborare l'ID di sistema per il fuso orario di Malta, ma si può farlo facilmente eseguendo il codice a livello locale:

Console.WriteLine(TimeZoneInfo.Local.Id); 

a giudicare dai vostri commenti, questo bit sarà irrilevante, ma solo per gli altri ...

Se siete non usando .NET 3.5, è necessario risolvere i legale da soli. Per essere onesti, il più semplice modo per farlo sta per essere una semplice tabella di ricerca. Elaborare le modifiche dell'ora legale per i prossimi anni, quindi scrivere un metodo semplice per restituire l'offset in una determinata ora UTC con tale elenco codificato. Si potrebbe desidera solo un ordinato List<DateTime> con i cambiamenti noti, e si alternano tra 1 e 2 ore fino a quando la data è dopo l'ultima modifica:

// 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, ho modificato la tua risposta per invertire i parametri di TimeZoneInfo.ConvertTimeFromUtc –

+0

Whoops, grazie. La cosa bizzarra è che li ho effettivamente controllati per primi - poi li ho fatti sbagliare comunque! –

+0

La soluzione sta generando questa eccezione nel metodo ConvertTimeFromUtc: Impossibile completare la conversione perché il DateTime fornito non ha impostato correttamente la proprietà Kind. Ad esempio, quando la proprietà Kind è DateTimeKind.Local, il fuso orario dell'origine deve essere TimeZoneInfo.Local. Nome parametro: sourceTimeZone –

Problemi correlati