Como: Permitir que usuários resolver Times ambíguos
Um horário ambíguo é um horário que aponta para mais de um Tempo Universal Coordenado (UTC).Ele ocorre quando a hora do relógio é atrasada, como durante a transição do horário de verão para o horário padrão de um fuso horário.Ao manipular um horário ambíguo, você pode fazer uma das seguintes opções:
Se o horário ambíguo for um item de dados inserido pelo usuário, você pode deixar para o usuário resolver a ambiguidade.
Faça uma suposição sobre como o tempo aponta para o UTC.Por exemplo, você pode supor que um horário ambíguo é sempre expresso no horário padrão do fuso horário.
Este tópico mostra como permitir que o usuário resolva um horário ambíguo.
Para permitir que um usuário resolva um horário ambíguo
Obtenha a data e a hora entradas pelo usuário.
Chame o método IsAmbiguousTime para determinar se o horário é ambíguo.
Se o horário for ambíguo, chame o método GetAmbiguousTimeOffsets para recuperar uma matriz de objetos TimeSpan.Cada elemento na matriz contém um deslocamento do UTC para o qual o horário ambíguo pode apontar.
Permita que o usuário selecione o deslocamento desejado.
Obtenha a data e a hora UTC subtraindo do horário local o deslocamento selecionado pelo usuário.
Chame o método static (Shared no Visual Basic .NET) SpecifyKind para definir a propriedade Kind do valor de data e hora UTC para DateTimeKind.Utc.
Exemplo
O exemplo a seguir solicita que o usuário insira uma data e hora e, se ela for ambígua, permite que o usuário selecione o horário UTC para o qual o horário ambíguo aponta.
Private Sub GetUserDateInput()
' Get date and time from user
Dim inputDate As Date = GetUserDateTime()
Dim utcDate As Date
' Exit if date has no significant value
If inputDate = Date.MinValue Then Exit Sub
If TimeZoneInfo.Local.IsAmbiguousTime(inputDate) Then
Console.WriteLine("The date you've entered is ambiguous.")
Console.WriteLine("Please select the correct offset from Universal Coordinated Time:")
Dim offsets() As TimeSpan = TimeZoneInfo.Local.GetAmbiguousTimeOffsets(inputDate)
For ctr As Integer = 0 to offsets.Length - 1
Dim zoneDescription As String
If offsets(ctr).Equals(TimeZoneInfo.Local.BaseUtcOffset) Then
zoneDescription = TimeZoneInfo.Local.StandardName
Else
zoneDescription = TimeZoneInfo.Local.DaylightName
End If
Console.WriteLine("{0}.) {1} hours, {2} minutes ({3})", _
ctr, offsets(ctr).Hours, offsets(ctr).Minutes, zoneDescription)
Next
Console.Write("> ")
Dim selection As Integer = CInt(Console.ReadLine())
' Convert local time to UTC, and set Kind property to DateTimeKind.Utc
utcDate = Date.SpecifyKind(inputDate - offsets(selection), DateTimeKind.Utc)
Console.WriteLine("{0} local time corresponds to {1} {2}.", inputDate, utcDate, utcDate.Kind.ToString())
Else
utcDate = inputDate.ToUniversalTime()
Console.WriteLine("{0} local time corresponds to {1} {2}.", inputDate, utcDate, utcDate.Kind.ToString())
End If
End Sub
Private Function GetUserDateTime() As Date
Dim exitFlag As Boolean = False ' flag to exit loop if date is valid
Dim dateString As String
Dim inputDate As Date = Date.MinValue
Console.Write("Enter a local date and time: ")
Do While Not exitFlag
dateString = Console.ReadLine()
If dateString.ToUpper = "E" Then exitFlag = True
If Date.TryParse(dateString, inputDate) Then
exitFlag = true
Else
Console.Write("Enter a valid date and time, or enter 'e' to exit: ")
End If
Loop
Return inputDate
End Function
private void GetUserDateInput()
{
// Get date and time from user
DateTime inputDate = GetUserDateTime();
DateTime utcDate;
// Exit if date has no significant value
if (inputDate == DateTime.MinValue) return;
if (TimeZoneInfo.Local.IsAmbiguousTime(inputDate))
{
Console.WriteLine("The date you've entered is ambiguous.");
Console.WriteLine("Please select the correct offset from Universal Coordinated Time:");
TimeSpan[] offsets = TimeZoneInfo.Local.GetAmbiguousTimeOffsets(inputDate);
for (int ctr = 0; ctr < offsets.Length; ctr++)
{
Console.WriteLine("{0}.) {1} hours, {2} minutes", ctr, offsets[ctr].Hours, offsets[ctr].Minutes);
}
Console.Write("> ");
int selection = Convert.ToInt32(Console.ReadLine());
// Convert local time to UTC, and set Kind property to DateTimeKind.Utc
utcDate = DateTime.SpecifyKind(inputDate - offsets[selection], DateTimeKind.Utc);
Console.WriteLine("{0} local time corresponds to {1} {2}.", inputDate, utcDate, utcDate.Kind.ToString());
}
else
{
utcDate = inputDate.ToUniversalTime();
Console.WriteLine("{0} local time corresponds to {1} {2}.", inputDate, utcDate, utcDate.Kind.ToString());
}
}
private DateTime GetUserDateTime()
{
bool exitFlag = false; // flag to exit loop if date is valid
string dateString;
DateTime inputDate = DateTime.MinValue;
Console.Write("Enter a local date and time: ");
while (! exitFlag)
{
dateString = Console.ReadLine();
if (dateString.ToUpper() == "E")
exitFlag = true;
if (DateTime.TryParse(dateString, out inputDate))
exitFlag = true;
else
Console.Write("Enter a valid date and time, or enter 'e' to exit: ");
}
return inputDate;
}
O núcleo do código de exemplo usa uma matriz de objetos TimeSpan para indicar possíveis deslocamentos do UTC do horário ambíguo.No entanto, esses deslocamentos provavelmente não serão significativos para o usuário.Para esclarecer o significado dos deslocamentos, o código também nota se um deslocamento representa o horário padrão do fuso horário local ou seu horário de verão.O código determina qual horário é padrão e qual é de verão comparando o deslocamento com o valor da propriedade BaseUtcOffset.Essa propriedade indica a diferença entre o UTC e o horário padrão do fuso horário.
Nesse exemplo, todas as referências para o fuso horário local são feitas através da propriedade TimeZoneInfo.Local; o fuso horário local nunca é atribuído a uma variável de objeto.Essa é uma prática recomendada pois uma chamada para o método TimeZoneInfo.ClearCachedData invalida quaisquer objetos aos quais o fuso horário local esteja atribuído.
Compilando o código
Este exemplo requer:
Que uma referência a System.Core.dll seja adicionada ao projeto.
Que o namespace System seja importado com a instrução using (necessária em código C#).