Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Está se tornando cada vez mais importante para qualquer aplicativo que funcione com datas e horas para lidar com diferenças entre fusos horários. Um aplicativo não pode mais assumir que todos os horários podem ser expressos na hora local, que é o tempo disponível na estrutura DateTime. Por exemplo, uma página da Web que exibe a hora atual na parte oriental dos Estados Unidos não terá credibilidade para um cliente no leste da Ásia. Este artigo explica como converter horários de um fuso horário para outro e converter valores que reconhecem fusos horários de forma limitada.
Convertendo em Tempo Universal Coordenado
O UTC (Tempo Universal Coordenado) é um padrão de tempo atômico de alta precisão. Os fusos horários do mundo são expressos como deslocamentos positivos ou negativos da UTC. Assim, o UTC fornece um fuso horário livre ou um tempo neutro de fuso horário. O uso de UTC é recomendado quando a portabilidade de uma data e hora entre computadores é importante. Para obter detalhes e outras práticas recomendadas usando datas e horas, consulte As melhores práticas de codificação usando DateTime no .NET Framework. A conversão de fusos horários individuais em UTC facilita as comparações de tempo.
Observação
Você também pode serializar uma DateTimeOffset estrutura para representar um único ponto no tempo de forma inequívoca. Objetos DateTimeOffset armazenam um valor de data e hora junto com seu deslocamento em relação ao UTC, portanto, eles sempre representam um ponto específico no tempo em relação ao UTC.
A maneira mais fácil de converter um tempo em UTC é chamar o método static (Shared no Visual Basic) TimeZoneInfo.ConvertTimeToUtc(DateTime). A conversão exata executada pelo método depende do valor da dateTime propriedade do Kind parâmetro, como mostra a tabela a seguir:
DateTime.Kind |
Conversão |
|---|---|
DateTimeKind.Local |
Converte a hora local em UTC. |
DateTimeKind.Unspecified |
Pressupõe que o dateTime parâmetro seja hora local e converte a hora local em UTC. |
DateTimeKind.Utc |
Retorna o dateTime parâmetro inalterado. |
O código a seguir converte a hora local atual em UTC e exibe o resultado no console:
DateTime dateNow = DateTime.Now;
Console.WriteLine($"The date and time are {TimeZoneInfo.ConvertTimeToUtc(dateNow)} UTC.");
Dim dateNow As Date = Date.Now
Console.WriteLine("The date and time are {0} UTC.", _
TimeZoneInfo.ConvertTimeToUtc(dateNow))
Se o valor de data e hora não representar a hora local ou UTC, o ToUniversalTime método provavelmente retornará um resultado incorreto. No entanto, você pode usar o TimeZoneInfo.ConvertTimeToUtc método para converter a data e a hora de um fuso horário especificado. Para obter detalhes sobre como recuperar um TimeZoneInfo objeto que representa o fuso horário de destino, consulte Localizar os fusos horários definidos em um sistema local. O código a seguir usa o TimeZoneInfo.ConvertTimeToUtc método para converter o Horário Padrão Oriental em 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 {TimeZoneInfo.ConvertTimeToUtc(easternTime, easternZone)} UTC.");
}
catch (TimeZoneNotFoundException)
{
Console.WriteLine($"Unable to find the {easternZoneId} zone in the registry.");
}
catch (InvalidTimeZoneException)
{
Console.WriteLine($"Registry data on the {easternZoneId} zone has been corrupted.");
}
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
O TimeZoneInfo.ConvertTimeToUtc método gera um ArgumentException se a DateTime propriedade do Kind objeto e o fuso horário forem incompatíveis. Uma incompatibilidade ocorrerá se a Kind propriedade for DateTimeKind.Local, mas o objeto TimeZoneInfo não representar o fuso horário local, ou se a Kind propriedade for DateTimeKind.Utc, mas o objeto TimeZoneInfo não for igual a TimeZoneInfo.Utc.
Todos esses métodos assumem DateTime valores como parâmetros e retornam um DateTime valor. Para DateTimeOffset valores, a estrutura DateTimeOffset possui um método de instância ToUniversalTime que converte a data e a hora da instância atual para UTC. O exemplo a seguir chama o método ToUniversalTime para converter uma hora local e vários outros horários em 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: {localTime}");
Console.WriteLine();
// Convert local time to offset 0 and assign to otherTime
otherTime = localTime.ToOffset(TimeSpan.Zero);
Console.WriteLine($"Other time: {otherTime}");
Console.WriteLine($"{localTime} = {otherTime}: {localTime.Equals(otherTime)}");
Console.WriteLine($"{localTime} exactly equals {otherTime}: {localTime.EqualsExact(otherTime)}");
Console.WriteLine();
// Convert other time to UTC
universalTime = localTime.ToUniversalTime();
Console.WriteLine($"Universal time: {universalTime}");
Console.WriteLine($"{otherTime} = {universalTime}: {universalTime.Equals(otherTime)}");
Console.WriteLine($"{otherTime} exactly equals {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
Convertendo UTC em um fuso horário designado
Para converter UTC em hora local, consulte a seção Converter UTC em hora local a seguir. Para converter o UTC para o horário em qualquer fuso horário que você designar, chame o método ConvertTimeFromUtc. O método utiliza dois parâmetros:
O horário UTC a ser convertido. Esse deve ser um DateTime valor cuja Kind propriedade está definida como
UnspecifiedouUtc.O fuso horário para o qual converter o UTC.
O código a seguir converte UTC em Hora Padrão Central:
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
Convertendo UTC em hora local
Para converter UTC em hora local, chame o ToLocalTime método do DateTime objeto cuja hora você deseja converter. O comportamento exato do método depende do valor da propriedade do Kind objeto, como mostra a tabela a seguir:
DateTime.Kind |
Conversão |
|---|---|
DateTimeKind.Local |
Retorna o DateTime valor inalterado. |
DateTimeKind.Unspecified |
Pressupõe que o DateTime valor é UTC e converte o UTC em hora local. |
DateTimeKind.Utc |
Converte o valor DateTime para hora local. |
Observação
O TimeZone.ToLocalTime método se comporta de forma idêntica ao DateTime.ToLocalTime método. Ele usa um único parâmetro, que é o valor de data e hora, para converter.
Você também pode converter a hora em qualquer fuso horário designado em hora local usando o static método (Shared no Visual Basic TimeZoneInfo.ConvertTime ). Essa técnica é discutida na próxima seção.
Convertendo entre quaisquer dois fusos horários
Você pode converter entre dois fusos horários usando um dos dois static seguintes métodos (Shared no Visual Basic) da TimeZoneInfo classe:
-
Os parâmetros desse método são o valor de data e hora a ser convertido, um
TimeZoneInfoobjeto que representa o fuso horário do valor de data e hora e umTimeZoneInfoobjeto que representa o fuso horário para o qual converter o valor de data e hora. -
Os parâmetros desse método são o valor de data e hora a ser convertido, o identificador do fuso horário do valor de data e hora e o identificador do fuso horário para o qual converter o valor de data e hora.
Ambos os métodos exigem que a Kind propriedade do valor de data e hora a ser convertida e o TimeZoneInfo identificador de objeto ou fuso horário que representa seu fuso horário corresponda um ao outro. Caso contrário, um ArgumentException será lançado. Por exemplo, se a Kind propriedade do valor de data e hora for DateTimeKind.Local, uma exceção será gerada se o TimeZoneInfo objeto passado como um parâmetro para o método não for igual a TimeZoneInfo.Local. Uma exceção também será gerada se o identificador passado como um parâmetro para o método não for igual a TimeZoneInfo.Local.Id.
O exemplo a seguir usa o ConvertTime método para converter de Hora Padrão Havaiana em hora local:
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
Convertendo valores de DateTimeOffset
Os valores de data e hora representados por DateTimeOffset objetos não estão totalmente cientes de fuso horário porque o objeto é desassociado de seu fuso horário no momento em que é instanciado. No entanto, em muitos casos, um aplicativo simplesmente precisa converter uma data e hora com base em dois deslocamentos diferentes de UTC em vez de no horário em determinados fusos horários. Para executar essa conversão, você pode chamar o método da ToOffset instância atual. O parâmetro único do método é o deslocamento do novo valor de data e hora que o método retornará.
Por exemplo, se a data e hora de uma solicitação de usuário para uma página da Web for conhecida e for serializada como uma cadeia de caracteres no formato MM/dd/yyyyy hh:mm:ss zzzz, o seguinte ReturnTimeOnServer método converterá esse valor de data e hora para a data e hora no servidor 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 o método passar a cadeia de caracteres "1/9/2007 5:32:07 -05:00", que representa a data e a hora em um fuso horário cinco horas antes do UTC, ele retorna "1/9/2007 3:32:07 AM -07:00" para um servidor localizado no fuso horário padrão do Pacífico dos EUA.
A TimeZoneInfo classe também inclui uma sobrecarga do TimeZoneInfo.ConvertTime(DateTimeOffset, TimeZoneInfo) método que executa conversões de fuso horário com ToOffset(TimeSpan) valores. Os parâmetros do método são um DateTimeOffset valor e uma referência ao fuso horário para o qual a hora deve ser convertida. A chamada de método retorna um DateTimeOffset valor. Por exemplo, o ReturnTimeOnServer método no exemplo anterior pode ser reescrito da seguinte maneira para chamar o ConvertTime(DateTimeOffset, TimeZoneInfo) método.
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