Dela via


Anvisningar: Låt användare lösa tvetydiga tider

En tvetydig tid är en tid som mappar till mer än en samordnad universell tid (UTC). Det inträffar när klocktiden justeras tillbaka i tiden, till exempel under övergången från en tidszons sommartid till dess standardtid. När du hanterar en tvetydig tid kan du göra något av följande:

  • Om den tvetydiga tiden är ett dataobjekt som användaren anger kan du låta användaren lösa tvetydigheten.

  • Gör ett antagande om hur tiden mappar till UTC. Du kan till exempel anta att en tvetydig tid alltid uttrycks i tidszonens standardtid.

Det här avsnittet visar hur du låter en användare lösa en tvetydig tid.

Så här låter du en användare lösa en tvetydig tid

  1. Hämta datum- och tidsindata från användaren.

  2. IsAmbiguousTime Anropa metoden för att avgöra om tiden är tvetydig.

  3. Om tiden är tvetydig anropar GetAmbiguousTimeOffsets du metoden för att hämta en matris med TimeSpan objekt. Varje element i matrisen innehåller en UTC-förskjutning som den tvetydiga tiden kan mappas till.

  4. Låt användaren välja önskad förskjutning.

  5. Hämta UTC-datum och tid genom att subtrahera den förskjutning som användaren har valt från den lokala tiden.

  6. static Anropa metoden (Shared i Visual Basic .NET) SpecifyKind för att ange utc-datum- och tidsvärdets Kind egenskap till DateTimeKind.Utc.

Exempel

I följande exempel uppmanas användaren att ange ett datum och en tid och, om det är tvetydigt, låter användaren välja den UTC-tid som den tvetydiga tiden mappar till.

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

Kärnan i exempelkoden använder en matris med TimeSpan objekt för att ange möjliga förskjutningar av den tvetydiga tiden från UTC. Dessa förskjutningar är dock osannolikt att vara meningsfulla för användaren. För att klargöra innebörden av förskjutningarna noterar koden även om en förskjutning representerar den lokala tidszonens standardtid eller dess sommartid. Koden avgör vilken tid som är standard och vilken tid som är dagsljus genom att jämföra förskjutningen med värdet för BaseUtcOffset egenskapen. Den här egenskapen anger skillnaden mellan UTC och tidszonens standardtid.

I det här exemplet görs alla referenser till den lokala tidszonen TimeZoneInfo.Local via egenskapen. Den lokala tidszonen tilldelas aldrig till en objektvariabel. Detta är en rekommenderad metod eftersom ett anrop till TimeZoneInfo.ClearCachedData metoden ogiltigförklarar alla objekt som den lokala tidszonen har tilldelats till.

Kompilera koden

Det här exemplet kräver:

  • System Att namnområdet importeras med -instruktionen using (krävs i C#-kod).

Se även