Partager via


Procédure : permettre aux utilisateurs de résoudre des heures ambiguës

Une heure ambiguë est une heure qui correspond à plusieurs heures UTC. Cela se produit lorsque l’heure de l’horloge est retardée, comme lors du passage à l’heure d’hiver dans un fuseau horaire. Lorsque vous gérez une heure ambiguë, vous pouvez procéder de l’une des manières suivantes :

  • Si l’heure ambiguë est un élément de données entré par l’utilisateur, vous pouvez laisser l’utilisateur résoudre l’ambiguïté.

  • Proposez une méthode de mappage à l’heure UTC. Par exemple, vous pouvez supposer qu’une heure ambiguë est toujours exprimée dans le cadre de l’heure d’hiver du fuseau horaire.

Cette rubrique montre comment permettre à un utilisateur de résoudre un problème d’heure ambiguë.

Pour permettre à un utilisateur de résoudre une heure ambiguë

  1. Obtenez la date et l’heure entrées par l’utilisateur.

  2. Appelez la méthode IsAmbiguousTime pour déterminer si l’heure est ambiguë.

  3. Si l’heure est ambiguë, appelez la méthode GetAmbiguousTimeOffsets pour récupérer un tableau d’objets TimeSpan. Chaque élément du tableau contient un décalage UTC auquel l’heure ambiguë peut être mappée.

  4. Laissez l’utilisateur sélectionner le décalage souhaité.

  5. Obtenez la date et l’heure UTC en soustrayant de l’heure locale le décalage sélectionné par l’utilisateur.

  6. Appelez la méthode static (Shared en Visual Basic .NET) SpecifyKind pour affecter la valeur DateTimeKind.Utc à la propriété Kind de la valeur de date et d’heure UTC.

Exemple

L’exemple suivant invite l’utilisateur à entrer une date et une heure et, si cette dernière est ambiguë, permet à l’utilisateur de sélectionner l’heure UTC à laquelle l’heure ambiguë correspond.

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($"{ctr}.) {offsets[ctr].Hours} hours, {offsets[ctr].Minutes} 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($"{inputDate} local time corresponds to {utcDate} {utcDate.Kind.ToString()}.");
    }
    else
    {
        utcDate = inputDate.ToUniversalTime();
        Console.WriteLine($"{inputDate} local time corresponds to {utcDate} {utcDate.Kind.ToString()}.");
    }
}

private static DateTime GetUserDateTime()
{
    // Flag to exit loop if date is valid.
    bool exitFlag = false;
    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;
}
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

La partie principale de cet exemple de code utilise un tableau d’objets TimeSpan pour indiquer les décalages possibles de l’heure ambiguë par rapport à l’heure UTC. Toutefois, ces décalages ne seront probablement pas significatifs pour l’utilisateur. Pour clarifier leur signification, le code note également si un décalage représente l’heure d’hiver du fuseau horaire local ou son heure d’été. Le code détermine l’heure d’hiver et l’heure d’été en comparant le décalage avec la valeur de la propriété BaseUtcOffset. Cette propriété indique la différence entre l’heure UTC et l’heure d’hiver du fuseau horaire.

Dans cet exemple, toutes les références au fuseau horaire local sont faites via la propriété TimeZoneInfo.Local ; le fuseau horaire local n’est jamais assigné à une variable objet. Il est recommandé d’utiliser cette méthode, car un autre appel à la méthode TimeZoneInfo.ClearCachedData invalide les objets auxquels le fuseau horaire local est assigné.

Voir aussi