Delen via


Procedure: Gebruikers toestaan om dubbelzinnige tijden op te lossen

Een dubbelzinnige tijd is een tijd die is toegewezen aan meer dan één Coordinated Universal Time (UTC). Het gebeurt wanneer de kloktijd weer in de tijd wordt aangepast, zoals tijdens de overgang van de zomertijd van een tijdzone naar de standaardtijd. Wanneer u een dubbelzinnige tijd verwerkt, kunt u een van de volgende handelingen uitvoeren:

  • Als de dubbelzinnige tijd een gegevensitem is dat door de gebruiker is ingevoerd, kunt u deze aan de gebruiker laten staan om de dubbelzinnigheid op te lossen.

  • Maak een aanname over hoe de tijd wordt toegewezen aan UTC. U kunt er bijvoorbeeld van uitgaan dat een dubbelzinnige tijd altijd wordt uitgedrukt in de standaardtijd van de tijdzone.

In dit onderwerp wordt beschreven hoe een gebruiker een dubbelzinnige tijd kan oplossen.

Een gebruiker een dubbelzinnige tijd laten oplossen

  1. De datum- en tijdinvoer van de gebruiker ophalen.

  2. Roep de IsAmbiguousTime methode aan om te bepalen of de tijd dubbelzinnig is.

  3. Als de tijd niet eenduidig is, roept u de GetAmbiguousTimeOffsets methode aan om een matrix met TimeSpan objecten op te halen. Elk element in de matrix bevat een UTC-offset waaraan de dubbelzinnige tijd kan worden toegewezen.

  4. Laat de gebruiker de gewenste offset selecteren.

  5. De UTC-datum en -tijd ophalen door de offset af te trekken die is geselecteerd door de gebruiker van de lokale tijd.

  6. Roep de static methode (Shared in Visual Basic .NET) SpecifyKind aan om de eigenschap UTC-datum en tijd Kind in te stellen op DateTimeKind.Utc.

Opmerking

In het volgende voorbeeld wordt de gebruiker gevraagd een datum en tijd in te voeren en, als deze dubbelzinnig is, kan de gebruiker de UTC-tijd selecteren waaraan de dubbelzinnige tijd is toegewezen.

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

De kern van de voorbeeldcode maakt gebruik van een matrix met TimeSpan objecten om mogelijke verschuivingen van de dubbelzinnige tijd van UTC aan te geven. Deze offsets zijn echter waarschijnlijk niet zinvol voor de gebruiker. Om de betekenis van de offsets te verduidelijken, noteert de code ook of een offset de standaardtijd van de lokale tijdzone of de zomertijd vertegenwoordigt. De code bepaalt welke tijd standaard is en welke tijd het daglicht is door de offset te vergelijken met de waarde van de BaseUtcOffset eigenschap. Deze eigenschap geeft het verschil aan tussen de UTC en de standaardtijd van de tijdzone.

In dit voorbeeld worden alle verwijzingen naar de lokale tijdzone gemaakt via de TimeZoneInfo.Local eigenschap. De lokale tijdzone wordt nooit toegewezen aan een objectvariabele. Dit is een aanbevolen procedure omdat een aanroep van de TimeZoneInfo.ClearCachedData methode alle objecten waaraan de lokale tijdzone is toegewezen, ongeldig maakt.

Zie ook