Bagikan melalui


Panduan: Membiarkan pengguna agar menyelesaikan waktu yang ambigu

Waktu ambigu adalah waktu yang memetakan ke lebih dari satu Waktu Universal Terkoordinasi (UTC). Ini terjadi ketika waktu jam disesuaikan kembali dalam waktu, seperti selama transisi dari waktu musim panas zona waktu ke waktu standarnya. Saat menangani waktu yang ambigu, Anda dapat melakukan salah satu hal berikut:

  • Jika waktu ambigu adalah item data yang dimasukkan oleh pengguna, Anda dapat menyerahkannya kepada pengguna untuk menyelesaikan ambiguitas.

  • Buat asumsi tentang bagaimana waktu memetakan ke UTC. Misalnya, Anda dapat mengasumsikan bahwa waktu ambigu selalu dinyatakan dalam waktu standar zona waktu.

Topik ini menunjukkan cara membiarkan pengguna menyelesaikan waktu yang ambigu.

Untuk membiarkan pengguna menyelesaikan waktu yang ambigu

  1. Dapatkan input tanggal dan waktu oleh pengguna.

  2. Panggil metode IsAmbiguousTime untuk menentukan apakah waktunya ambigu.

  3. Jika waktunya ambigu, panggil GetAmbiguousTimeOffsets metode untuk mengambil array TimeSpan objek. Setiap elemen dalam array berisi offset UTC yang dapat dipetakan oleh waktu ambigu.

  4. Biarkan pengguna memilih offset yang diinginkan.

  5. Dapatkan tanggal dan waktu UTC dengan mengurangi offset yang dipilih oleh pengguna dari waktu setempat.

  6. Panggil static metode (Shared dalam Visual Basic .NET) SpecifyKind untuk mengatur properti nilai tanggal dan waktu Kind UTC ke DateTimeKind.Utc.

Contoh

Contoh berikut meminta pengguna untuk memasukkan tanggal dan waktu dan, jika ambigu, memungkinkan pengguna memilih waktu UTC yang dipetakan oleh waktu ambigu.

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

Inti dari kode contoh menggunakan array TimeSpan objek untuk menunjukkan kemungkinan offset waktu ambigu dari UTC. Namun, offset ini tidak mungkin berarti bagi pengguna. Untuk memperjelas arti offset, kode juga mencatat apakah offset mewakili waktu standar zona waktu setempat atau waktu musim panasnya. Kode menentukan waktu mana yang standar dan waktu mana yang merupakan siang hari dengan membandingkan offset dengan nilai BaseUtcOffset properti. Properti ini menunjukkan perbedaan antara UTC dengan waktu standar zona waktu.

Dalam contoh ini, semua referensi ke zona waktu lokal dibuat melalui TimeZoneInfo.Local properti; zona waktu lokal tidak pernah ditetapkan ke variabel objek. Ini adalah praktik yang direkomendasikan karena panggilan ke metode TimeZoneInfo.ClearCachedData membatalkan objek apa pun yang ditetapkan zona waktu lokal.

Mengompilasi kode

Contoh ini membutuhkan:

  • Bahwa namespace layanan System diimpor dengan pernyataan using (diperlukan dalam kode C#).

Lihat juga