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
Dapatkan input tanggal dan waktu oleh pengguna.
Panggil metode IsAmbiguousTime untuk menentukan apakah waktunya ambigu.
Jika waktunya ambigu, panggil GetAmbiguousTimeOffsets metode untuk mengambil array TimeSpan objek. Setiap elemen dalam array berisi offset UTC yang dapat dipetakan oleh waktu ambigu.
Biarkan pengguna memilih offset yang diinginkan.
Dapatkan tanggal dan waktu UTC dengan mengurangi offset yang dipilih oleh pengguna dari waktu setempat.
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.