2010-03-30 8 views
23

Ho un valore DateTime UTC proveniente da un record del database. Ho anche un fuso orario specificato dall'utente (un'istanza di TimeZoneInfo). Come posso convertire l'UTC DateTime nel fuso orario locale dell'utente? Inoltre, come determinare se il fuso orario specificato dall'utente sta attualmente osservando l'ora legale? Sto usando .NET 3.5.Converti UTC DateTime in un altro fuso orario

Grazie, Mark

risposta

20

Date un'occhiata alla struttura di DateTimeOffset:

// user-specified time zone 
TimeZoneInfo southPole = 
    TimeZoneInfo.FindSystemTimeZoneById("Antarctica/South Pole Standard Time"); 

// an UTC DateTime 
DateTime utcTime = new DateTime(2007, 07, 12, 06, 32, 00, DateTimeKind.Utc); 

// DateTime with offset 
DateTimeOffset dateAndOffset = 
    new DateTimeOffset(utcTime, southPole.GetUtcOffset(utcTime)); 

Console.WriteLine(dateAndOffset); 

Per DST vedere il metodo TimeZoneInfo.IsDaylightSavingTime.

bool isDst = southpole.IsDaylightSavingTime(DateTime.UtcNow); 
+0

devo fare un passo in più per ottenere la mia ora locale: var offset = tzi.GetUtcOffset (UTCTime); var siteLocalTime = utcTime.Add (offset); return siteLocalTime.ToString ("MM/gg/aaaa HH: mm"); –

+5

Questo codice non viene compilato. L'ID del fuso orario non esiste e se lo si sostituisce con uno valido, si ottiene un errore relativo a "L'offset UTC per le istanze Date Utc di Utc deve essere 0". –

+0

per evitare errori in dateAndOffset scegliere DateTime cstTime = utcTime.AddTicks (southPole.BaseUtcOffset.Ticks); –

11

La risposta di Antartica funziona solo per i fusi orari corrispondenti a UTC. Sono abbastanza traumatizzato con questa funzione DateTimeOffset e dopo ore di tentativi ed errori, sono riuscito a produrre una pratica funzione di estensione di conversione che funziona con tutti i fusi orari.

static public class DateTimeFunctions 
{ 
    static public DateTimeOffset ConvertUtcTimeToTimeZone(this DateTime dateTime, string toTimeZoneDesc) 
    { 
     if (dateTime.Kind != DateTimeKind.Utc) throw new Exception("dateTime needs to have Kind property set to Utc"); 
     var toUtcOffset = TimeZoneInfo.FindSystemTimeZoneById(toTimeZoneDesc).GetUtcOffset(dateTime); 
     var convertedTime = DateTime.SpecifyKind(dateTime.Add(toUtcOffset), DateTimeKind.Unspecified); 
     return new DateTimeOffset(convertedTime, toUtcOffset); 
    } 
} 

Esempio:

var currentTimeInPacificTime = DateTime.UtcNow.ConvertUtcTimeToTimeZone("Pacific Standard Time"); 
+5

'public static'? HERESY, BURN THE WITCH –

20

è possibile utilizzare una funzione dedicata all'interno TimeZoneInfo se si desidera convertire un DateTimeOffset in un altro DateTimeOffset:

DateTimeOffset newTime = TimeZoneInfo.ConvertTime(
    DateTimeOffset.UtcNow, 
    TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time") 
); 
24

Il modo migliore per farlo è semplicemente utilizzare TimeZoneInfo.ConvertTimeFromUtc.

// you said you had these already 
DateTime utc = new DateTime(2014, 6, 4, 12, 34, 0); 
TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time"); 

// it's a simple one-liner 
DateTime pacific = TimeZoneInfo.ConvertTimeFromUtc(utc, tzi); 

L'unico problema è che il valore in ingresso DateTime non può avere l'DateTimeKind.Local tipo. Deve essere Utc o Unspecified.

0
 // TO get Currrent Time in current Time Zone of your System 

     var dt = DateTime.Now; 

     Console.WriteLine(dt); 

     // Display Time Zone of your System 

     Console.WriteLine(TimeZoneInfo.Local); 

     // Convert Current Date Time to UTC Date Time 

     var utc = TimeZoneInfo.ConvertTimeToUtc(dt, TimeZoneInfo.Local); 

     Console.WriteLine(utc); 

     // Convert UTC Time to Current Time Zone 

     DateTime pacific = TimeZoneInfo.ConvertTimeFromUtc(utc, TimeZoneInfo.Local); 

     Console.WriteLine(pacific); 

     Console.ReadLine();