Nasıl yapılır: Kullanıcıların belirsiz saatleri çözmelerine izin verme

Belirsiz bir saat, birden fazla Eşgüdümlü Evrensel Saat 'e (UTC) eşlenen bir zamandır. Saat saati, örneğin bir saat diliminin gün ışığından standart saatine geçiş sırasında olduğu gibi zamanda geri ayarlandığında oluşur. Belirsiz bir zamanı işlerken aşağıdakilerden birini yapabilirsiniz:

  • Belirsiz saat, kullanıcının girdiği bir veri öğesiyse, belirsizliği çözmek için bunu kullanıcıya bırakabilirsiniz.

  • Saatin UTC'ye nasıl eş olduğu hakkında bir varsayımda bulunın. Örneğin, belirsiz bir saatin her zaman saat diliminin standart saatinde ifade edildiği varsayılabilir.

Bu konuda, bir kullanıcının belirsiz bir zamanı çözmesine nasıl izin vereceğinizi gösterir.

Kullanıcının belirsiz bir zamanı çözmesine izin vermek için

  1. Kullanıcı tarafından tarih ve saat girişini alın.

  2. IsAmbiguousTime Saatin belirsiz olup olmadığını belirlemek için yöntemini çağırın.

  3. Zaman belirsizse, bir nesne dizisi almak için yöntemini çağırın GetAmbiguousTimeOffsetsTimeSpan . Dizideki her öğe, belirsiz saatin eşleyebilecekleri bir UTC uzaklığı içerir.

  4. Kullanıcının istenen uzaklığı seçmesine izin verin.

  5. Kullanıcı tarafından seçilen uzaklığı yerel saatten çıkararak UTC tarih ve saatini alın.

  6. UTC tarih ve saat değerinin static özelliğini DateTimeKind.Utcolarak ayarlamak için (Shared Visual Basic .NET'te) SpecifyKind yöntemini çağırınKind.

Örnek

Aşağıdaki örnek, kullanıcıdan bir tarih ve saat girmesini ister ve belirsizse, kullanıcının belirsiz saatin eşlendiğini UTC saatini seçmesine izin verir.

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

Örnek kodun çekirdeği, belirsiz saatin UTC'den olası uzaklıklarını göstermek için bir nesne dizisi TimeSpan kullanır. Ancak, bu uzaklıkların kullanıcı için anlamlı olma olasılığı düşüktür. Kod, uzaklıkların anlamını netleştirmek için, uzaklık yerel saat diliminin standart saatini mi yoksa yaz saati saatini mi temsil eder? Kod, uzaklığı özelliğin değeriyle BaseUtcOffset karşılaştırarak hangi saatin standart ve hangi saatin gün ışığı olduğunu belirler. Bu özellik UTC ile saat diliminin standart saati arasındaki farkı gösterir.

Bu örnekte, yerel saat dilimine yapılan tüm başvurular özelliği aracılığıyla TimeZoneInfo.Local yapılır; yerel saat dilimi hiçbir zaman bir nesne değişkenine atanmamaktadır. Yöntemine yapılan bir çağrı, yerel saat diliminin TimeZoneInfo.ClearCachedData atandığı tüm nesneleri geçersiz kıldığından bu önerilen bir uygulamadır.

Kod derleme

Bu örnek şunları gerektirir:

  • Ad alanının System deyimiyle içeri aktarılması ( using C# kodunda gereklidir).

Ayrıca bkz.