Como: resolver horários ambíguos

Um horário ambíguo é um horário que aponta para mais de um UTC (Tempo Universal Coordenado). Ocorre quando o horário do relógio é atrasado, como durante a transição do horário de verão de um fuso horário para seu horário padrão. Ao processar um horário ambíguo, você pode executar uma das seguintes ações:

  • Faça uma suposição de 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.

  • Se o horário ambíguo for um item de dados inserido pelo usuário, você pode deixar que o usuário resolva a ambiguidade.

Este tópico mostra como resolver um horário ambíguo supondo que ele representa o horário padrão do fuso horário.

Para apontar um horário ambíguo para o horário padrão de um fuso horário

  1. Chame o método IsAmbiguousTime para determinar se o horário é ambíguo.

  2. Se o horário for ambíguo, subtraia o horário do objeto TimeSpan retornado pela propriedade BaseUtcOffset do fuso horário.

  3. Chame o método static (Shared no Visual Basic .NET) SpecifyKind para definir a propriedade Kind do valor de data e de hora UTC como DateTimeKind.Utc.

Exemplo

O exemplo a seguir mostra como converter um horário ambíguo em UTC supondo que representa o horário padrão do fuso horário local.

private static DateTime ResolveAmbiguousTime(DateTime ambiguousTime)
{
    // Time is not ambiguous
    if (!TimeZoneInfo.Local.IsAmbiguousTime(ambiguousTime))
    {
        return ambiguousTime;
    }
    // Time is ambiguous
    else
    {
        DateTime utcTime = DateTime.SpecifyKind(ambiguousTime - TimeZoneInfo.Local.BaseUtcOffset,
                                                DateTimeKind.Utc);
        Console.WriteLine("{0} local time corresponds to {1} {2}.",
                          ambiguousTime, utcTime, utcTime.Kind.ToString());
        return utcTime;
    }
}
Private Function ResolveAmbiguousTime(ambiguousTime As Date) As Date
    ' Time is not ambiguous
    If Not TimeZoneInfo.Local.IsAmbiguousTime(ambiguousTime) Then
        Return TimeZoneInfo.ConvertTimeToUtc(ambiguousTime)
        ' Time is ambiguous
    Else
        Dim utcTime As Date = DateTime.SpecifyKind(ambiguousTime - TimeZoneInfo.Local.BaseUtcOffset, DateTimeKind.Utc)
        Console.WriteLine("{0} local time corresponds to {1} {2}.", ambiguousTime, utcTime, utcTime.Kind.ToString())
        Return utcTime
    End If
End Function

O exemplo consiste em um método chamado ResolveAmbiguousTime que determina se o valor DateTime passado para ele é ambíguo. Se o valor for ambíguo, o método retorna um valor DateTime que representa o horário UTC correspondente. O método trata essa conversão subtraindo do horário local o valor da propriedade BaseUtcOffset do fuso horário local.

Normalmente, um horário ambíguo é tratado chamando o método GetAmbiguousTimeOffsets para recuperar uma matriz de objetos TimeSpan que contêm as possíveis diferenças de UTC do horário ambíguo. No entanto, esse exemplo faz a suposição arbitrária de que um horário ambíguo deve sempre apontar para o horário padrão do fuso horário. A propriedade BaseUtcOffset retorna a diferença entre o UTC e o horário padrão de um fuso horário.

Neste exemplo, todas as referências ao 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, porque uma chamada ao método TimeZoneInfo.ClearCachedData invalida todos os objetos aos quais o fuso horário local esteja atribuído.

Confira também