Conversione degli orari tra fusi orari
È sempre più importante per qualsiasi applicazione che funziona con date e orari per gestire le differenze tra i fusi orari. Un'applicazione non può più presumere che tutti i tempi possano essere espressi nell'ora locale, ovvero il tempo disponibile dalla DateTime struttura. Ad esempio, una pagina Web che visualizza l'ora corrente nella parte orientale della Stati Uniti non avrà credibilità per un cliente nell'Asia orientale. Questo articolo illustra come convertire i tempi da un fuso orario a un altro e convertire DateTimeOffset i valori con consapevolezza limitata del fuso orario.
Conversione nel formato UTC
UTC (Coordinated Universal Time) è uno standard di alta precisione basato sul tempo atomico. I fusi orari del mondo vengono espressi come offset positivi o negativi da UTC. In questo modo, UTC fornisce un fuso orario libero o un fuso orario neutrale. L'uso dell'ora UTC è consigliato quando la portabilità di una data e dell'ora tra i computer è importante. Per informazioni dettagliate e altre procedure consigliate che usano date e ore, vedere Procedure consigliate per la codifica con DateTime in .NET Framework. La conversione di singoli fusi orari in ore UTC semplifica i confronti tra gli orari.
Nota
È anche possibile serializzare una struttura per rappresentare un DateTimeOffset singolo punto nel tempo senza ambiguità. Poiché DateTimeOffset gli oggetti archiviano un valore di data e ora insieme al relativo offset da UTC, rappresentano sempre un determinato punto di tempo rispetto all'ora UTC.
Il modo più semplice per convertire un'ora utc consiste nel chiamare il static
metodo (Shared
in Visual Basic). TimeZoneInfo.ConvertTimeToUtc(DateTime) La conversione esatta eseguita dal metodo dipende dal valore della proprietà del dateTime
Kind parametro, come illustrato nella tabella seguente:
DateTime.Kind |
Conversione |
---|---|
DateTimeKind.Local |
Converte l'ora locale in ora UTC. |
DateTimeKind.Unspecified |
Presuppone che il parametro dateTime sia l'ora locale e converte l'ora locale in ora UTC. |
DateTimeKind.Utc |
Restituisce il parametro dateTime invariato. |
Il codice seguente converte l'ora locale corrente in UTC e visualizza il risultato nella console:
DateTime dateNow = DateTime.Now;
Console.WriteLine("The date and time are {0} UTC.",
TimeZoneInfo.ConvertTimeToUtc(dateNow));
Dim dateNow As Date = Date.Now
Console.WriteLine("The date and time are {0} UTC.", _
TimeZoneInfo.ConvertTimeToUtc(dateNow))
Se il valore di data e ora non rappresenta l'ora locale o l'ora UTC, il ToUniversalTime metodo restituirà probabilmente un risultato errato. È tuttavia possibile usare il metodo per convertire la data e l'ora TimeZoneInfo.ConvertTimeToUtc da un fuso orario specificato. Per informazioni dettagliate sul recupero di un TimeZoneInfo oggetto che rappresenta il fuso orario di destinazione, vedere Ricerca dei fusi orari definiti in un sistema locale. Il codice seguente usa il metodo per convertire l'ora TimeZoneInfo.ConvertTimeToUtc standard orientale in utc:
DateTime easternTime = new DateTime(2007, 01, 02, 12, 16, 00);
string easternZoneId = "Eastern Standard Time";
try
{
TimeZoneInfo easternZone = TimeZoneInfo.FindSystemTimeZoneById(easternZoneId);
Console.WriteLine("The date and time are {0} UTC.",
TimeZoneInfo.ConvertTimeToUtc(easternTime, easternZone));
}
catch (TimeZoneNotFoundException)
{
Console.WriteLine("Unable to find the {0} zone in the registry.",
easternZoneId);
}
catch (InvalidTimeZoneException)
{
Console.WriteLine("Registry data on the {0} zone has been corrupted.",
easternZoneId);
}
Dim easternTime As New Date(2007, 01, 02, 12, 16, 00)
Dim easternZoneId As String = "Eastern Standard Time"
Try
Dim easternZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(easternZoneId)
Console.WriteLine("The date and time are {0} UTC.", _
TimeZoneInfo.ConvertTimeToUtc(easternTime, easternZone))
Catch e As TimeZoneNotFoundException
Console.WriteLine("Unable to find the {0} zone in the registry.", _
easternZoneId)
Catch e As InvalidTimeZoneException
Console.WriteLine("Registry data on the {0} zone has been corrupted.", _
easternZoneId)
End Try
Il TimeZoneInfo.ConvertTimeToUtc metodo genera un valore ArgumentException se la DateTime proprietà dell'oggetto Kind e il fuso orario non corrispondono. Una mancata corrispondenza si verifica se la Kind proprietà è ma l'oggetto non rappresenta il TimeZoneInfo fuso orario locale o se la proprietà è DateTimeKind.Local ma l'oggetto KindTimeZoneInfo non è DateTimeKind.Utc uguale TimeZoneInfo.Utca .
Tutti questi metodi accettano DateTime valori come parametri e restituiscono un DateTime valore. Per DateTimeOffset i valori, la DateTimeOffset struttura ha un ToUniversalTime metodo di istanza che converte la data e l'ora dell'istanza corrente in UTC. Nell'esempio seguente viene chiamato il ToUniversalTime metodo per convertire un'ora locale e diverse volte in formato UTC:
DateTimeOffset localTime, otherTime, universalTime;
// Define local time in local time zone
localTime = new DateTimeOffset(new DateTime(2007, 6, 15, 12, 0, 0));
Console.WriteLine("Local time: {0}", localTime);
Console.WriteLine();
// Convert local time to offset 0 and assign to otherTime
otherTime = localTime.ToOffset(TimeSpan.Zero);
Console.WriteLine("Other time: {0}", otherTime);
Console.WriteLine("{0} = {1}: {2}",
localTime, otherTime,
localTime.Equals(otherTime));
Console.WriteLine("{0} exactly equals {1}: {2}",
localTime, otherTime,
localTime.EqualsExact(otherTime));
Console.WriteLine();
// Convert other time to UTC
universalTime = localTime.ToUniversalTime();
Console.WriteLine("Universal time: {0}", universalTime);
Console.WriteLine("{0} = {1}: {2}",
otherTime, universalTime,
universalTime.Equals(otherTime));
Console.WriteLine("{0} exactly equals {1}: {2}",
otherTime, universalTime,
universalTime.EqualsExact(otherTime));
Console.WriteLine();
// The example produces the following output to the console:
// Local time: 6/15/2007 12:00:00 PM -07:00
//
// Other time: 6/15/2007 7:00:00 PM +00:00
// 6/15/2007 12:00:00 PM -07:00 = 6/15/2007 7:00:00 PM +00:00: True
// 6/15/2007 12:00:00 PM -07:00 exactly equals 6/15/2007 7:00:00 PM +00:00: False
//
// Universal time: 6/15/2007 7:00:00 PM +00:00
// 6/15/2007 7:00:00 PM +00:00 = 6/15/2007 7:00:00 PM +00:00: True
// 6/15/2007 7:00:00 PM +00:00 exactly equals 6/15/2007 7:00:00 PM +00:00: True
Dim localTime, otherTime, universalTime As DateTimeOffset
' Define local time in local time zone
localTime = New DateTimeOffset(#6/15/2007 12:00:00PM#)
Console.WriteLine("Local time: {0}", localTime)
Console.WriteLine()
' Convert local time to offset 0 and assign to otherTime
otherTime = localTime.ToOffset(TimeSpan.Zero)
Console.WriteLine("Other time: {0}", otherTime)
Console.WriteLine("{0} = {1}: {2}", _
localTime, otherTime, _
localTime.Equals(otherTime))
Console.WriteLine("{0} exactly equals {1}: {2}", _
localTime, otherTime, _
localTime.EqualsExact(otherTime))
Console.WriteLine()
' Convert other time to UTC
universalTime = localTime.ToUniversalTime()
Console.WriteLine("Universal time: {0}", universalTime)
Console.WriteLine("{0} = {1}: {2}", _
otherTime, universalTime, _
universalTime.Equals(otherTime))
Console.WriteLine("{0} exactly equals {1}: {2}", _
otherTime, universalTime, _
universalTime.EqualsExact(otherTime))
Console.WriteLine()
' The example produces the following output to the console:
' Local time: 6/15/2007 12:00:00 PM -07:00
'
' Other time: 6/15/2007 7:00:00 PM +00:00
' 6/15/2007 12:00:00 PM -07:00 = 6/15/2007 7:00:00 PM +00:00: True
' 6/15/2007 12:00:00 PM -07:00 exactly equals 6/15/2007 7:00:00 PM +00:00: False
'
' Universal time: 6/15/2007 7:00:00 PM +00:00
' 6/15/2007 7:00:00 PM +00:00 = 6/15/2007 7:00:00 PM +00:00: True
' 6/15/2007 7:00:00 PM +00:00 exactly equals 6/15/2007 7:00:00 PM +00:00: True
Conversione dell'ora UTC in un determinato fuso orario
Per convertire l'ora UTC nell'ora locale, vedere la sezione seguente Conversione dell'ora UTC nell'ora locale. Per convertire UTC nell'ora in qualsiasi fuso orario designato, chiamare il ConvertTimeFromUtc metodo . Il metodo accetta due parametri:
L'ora UTC da convertire. Questo deve essere un DateTime valore la cui Kind proprietà è impostata su
Unspecified
oUtc
.Il fuso orario nel quale convertire l'ora UTC.
Il codice seguente converte UTC in Ora standard centrale:
DateTime timeUtc = DateTime.UtcNow;
try
{
TimeZoneInfo cstZone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
DateTime cstTime = TimeZoneInfo.ConvertTimeFromUtc(timeUtc, cstZone);
Console.WriteLine("The date and time are {0} {1}.",
cstTime,
cstZone.IsDaylightSavingTime(cstTime) ?
cstZone.DaylightName : cstZone.StandardName);
}
catch (TimeZoneNotFoundException)
{
Console.WriteLine("The registry does not define the Central Standard Time zone.");
}
catch (InvalidTimeZoneException)
{
Console.WriteLine("Registry data on the Central Standard Time zone has been corrupted.");
}
Dim timeUtc As Date = Date.UtcNow
Try
Dim cstZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time")
Dim cstTime As Date = TimeZoneInfo.ConvertTimeFromUtc(timeUtc, cstZone)
Console.WriteLine("The date and time are {0} {1}.", _
cstTime, _
IIf(cstZone.IsDaylightSavingTime(cstTime), _
cstZone.DaylightName, cstZone.StandardName))
Catch e As TimeZoneNotFoundException
Console.WriteLine("The registry does not define the Central Standard Time zone.")
Catch e As InvalidTimeZoneException
Console.WriteLine("Registry data on the Central Standard Time zone has been corrupted.")
End Try
Conversione dell'ora UTC nell'ora locale
Per convertire utc in ora locale, chiamare il ToLocalTime metodo dell'oggetto DateTime il cui tempo si vuole convertire. Il comportamento esatto del metodo dipende dal valore della proprietà dell'oggetto Kind , come illustrato nella tabella seguente:
DateTime.Kind |
Conversione |
---|---|
DateTimeKind.Local |
Restituisce il DateTime valore invariato. |
DateTimeKind.Unspecified |
Si presuppone che il DateTime valore sia UTC e converte l'ora UTC in ora locale. |
DateTimeKind.Utc |
Converte il DateTime valore in ora locale. |
Nota
Il TimeZone.ToLocalTime metodo si comporta in modo identico al DateTime.ToLocalTime
metodo. Accetta un singolo parametro, ovvero il valore data e ora, per la conversione.
È anche possibile convertire l'ora in qualsiasi fuso orario designato in ora locale usando il static
metodo (Shared
in Visual Basic). TimeZoneInfo.ConvertTime Questa tecnica viene illustrata nella sezione successiva.
Conversione tra due fusi orari
È possibile convertire tra due fusi orari usando uno dei due static
metodi seguenti (Shared
in Visual Basic) della TimeZoneInfo classe:
-
I parametri di questo metodo sono il valore data e ora da convertire, un oggetto che rappresenta il fuso orario del valore di data e ora e un
TimeZoneInfo
TimeZoneInfo
oggetto che rappresenta il fuso orario in cui convertire il valore di data e ora. -
I parametri di questo metodo sono il valore di data e ora da convertire, l'identificatore del fuso orario della data e dell'ora e l'identificatore del fuso orario in cui convertire il valore di data e ora.
Entrambi i metodi richiedono che la Kind proprietà del valore di data e ora per convertire e l'identificatore del fuso orario o dell'oggetto che rappresenta il fuso orario corrispondano l'uno all'altro TimeZoneInfo . In caso contrario, verrà generata un'eccezione ArgumentException. Ad esempio, se la Kind
proprietà del valore di data e ora è DateTimeKind.Local
, viene generata un'eccezione se l'oggetto TimeZoneInfo
passato come parametro al metodo non è uguale a TimeZoneInfo.Local
. Viene generata anche un'eccezione se l'identificatore passato come parametro al metodo non è uguale a TimeZoneInfo.Local.Id
.
Nell'esempio seguente viene usato il metodo per convertire dall'ora standard hawaiiana all'ora ConvertTime locale:
DateTime hwTime = new DateTime(2007, 02, 01, 08, 00, 00);
try
{
TimeZoneInfo hwZone = TimeZoneInfo.FindSystemTimeZoneById("Hawaiian Standard Time");
Console.WriteLine("{0} {1} is {2} local time.",
hwTime,
hwZone.IsDaylightSavingTime(hwTime) ? hwZone.DaylightName : hwZone.StandardName,
TimeZoneInfo.ConvertTime(hwTime, hwZone, TimeZoneInfo.Local));
}
catch (TimeZoneNotFoundException)
{
Console.WriteLine("The registry does not define the Hawaiian Standard Time zone.");
}
catch (InvalidTimeZoneException)
{
Console.WriteLine("Registry data on the Hawaiian Standard Time zone has been corrupted.");
}
Dim hwTime As Date = #2/01/2007 8:00:00 AM#
Try
Dim hwZone As TimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("Hawaiian Standard Time")
Console.WriteLine("{0} {1} is {2} local time.", _
hwTime, _
IIf(hwZone.IsDaylightSavingTime(hwTime), hwZone.DaylightName, hwZone.StandardName), _
TimeZoneInfo.ConvertTime(hwTime, hwZone, TimeZoneInfo.Local))
Catch e As TimeZoneNotFoundException
Console.WriteLine("The registry does not define the Hawaiian Standard Time zone.")
Catch e As InvalidTimeZoneException
Console.WriteLine("Registry data on the Hawaiian Standard Time zone has been corrupted.")
End Try
Conversione dei valori DateTimeOffset
I valori di data e ora rappresentati dagli DateTimeOffset oggetti non sono completamente consapevoli del fuso orario perché l'oggetto viene disassociato dal relativo fuso orario alla volta in cui viene creata un'istanza. Tuttavia, in molti casi, un'applicazione deve semplicemente convertire una data e un'ora in base a due offset diversi da UTC anziché in orario in determinati fusi orari. Per eseguire questa conversione, è possibile chiamare il metodo dell'istanza ToOffset corrente. Il parametro singolo del metodo è l'offset del nuovo valore di data e ora restituito dal metodo.
Ad esempio, se la data e l'ora di una richiesta utente per una pagina Web è nota e viene serializzata come stringa nel formato MM/dd/a hh:mm:ss zzzz, il metodo seguente ReturnTimeOnServer
converte questo valore di data e ora nel server Web:
public DateTimeOffset ReturnTimeOnServer(string clientString)
{
string format = @"M/d/yyyy H:m:s zzz";
TimeSpan serverOffset = TimeZoneInfo.Local.GetUtcOffset(DateTimeOffset.Now);
try
{
DateTimeOffset clientTime = DateTimeOffset.ParseExact(clientString, format, CultureInfo.InvariantCulture);
DateTimeOffset serverTime = clientTime.ToOffset(serverOffset);
return serverTime;
}
catch (FormatException)
{
return DateTimeOffset.MinValue;
}
}
Public Function ReturnTimeOnServer(clientString As String) As DateTimeOffset
Dim format As String = "M/d/yyyy H:m:s zzz"
Dim serverOffset As TimeSpan = TimeZoneInfo.Local.GetUtcOffset(DateTimeOffset.Now)
Try
Dim clientTime As DateTimeOffset = DateTimeOffset.ParseExact(clientString, format, CultureInfo.InvariantCulture)
Dim serverTime As DateTimeOffset = clientTime.ToOffset(serverOffset)
Return serverTime
Catch e As FormatException
Return DateTimeOffset.MinValue
End Try
End Function
Se il metodo passa la stringa "9/1/2007 5:32:07 -05:00", che rappresenta la data e l'ora in un fuso orario di cinque ore precedenti all'ora UTC, restituisce "9/1/2007 3:32:07 AM -07:00" per un server che si trova nel fuso orario standard degli Stati Uniti.
La TimeZoneInfo classe include anche un overload del metodo che esegue conversioni del TimeZoneInfo.ConvertTime(DateTimeOffset, TimeZoneInfo) fuso orario con ToOffset(TimeSpan) valori. I parametri del metodo sono un valore e un DateTimeOffset riferimento al fuso orario in cui deve essere convertito l'ora. La chiamata al metodo restituisce un DateTimeOffset valore. Ad esempio, il ReturnTimeOnServer
metodo nell'esempio precedente può essere riscritto come segue per chiamare il ConvertTime(DateTimeOffset, TimeZoneInfo) metodo.
public DateTimeOffset ReturnTimeOnServer(string clientString)
{
string format = @"M/d/yyyy H:m:s zzz";
try
{
DateTimeOffset clientTime = DateTimeOffset.ParseExact(clientString, format,
CultureInfo.InvariantCulture);
DateTimeOffset serverTime = TimeZoneInfo.ConvertTime(clientTime,
TimeZoneInfo.Local);
return serverTime;
}
catch (FormatException)
{
return DateTimeOffset.MinValue;
}
}
Public Function ReturnTimeOnServer(clientString As String) As DateTimeOffset
Dim format As String = "M/d/yyyy H:m:s zzz"
Try
Dim clientTime As DateTimeOffset = DateTimeOffset.ParseExact(clientString, format, CultureInfo.InvariantCulture)
Dim serverTime As DateTimeOffset = TimeZoneInfo.ConvertTime(clientTime, TimeZoneInfo.Local)
Return serverTime
Catch e As FormatException
Return DateTimeOffset.MinValue
End Try
End Function
Vedi anche
Commenti e suggerimenti
Invia e visualizza il feedback per