Postupy: Rozpoznání nejednoznačných časů uživatelem
Nejednoznačný čas je čas, který je mapován na více než jeden koordinovaný světový čas (standard UTC). K tomu dojde, když je čas se upraven směrem zpět, například při přechodu z letního času na standardní čas. Při zpracování nejednoznačného času můžete provést jedno z následujících:
Pokud je nejednoznačný čas položkou dat zadaných uživatelem, můžete vyřešení nejednoznačnosti ponechat na uživateli.
Zkontrolujte předpoklady o tom, jak je čas mapován na čas UTC. Předpokládejme například, že nejednoznačný čas je vždy vyjádřen ve standardním času časového pásma.
Toto téma ukazuje, jak nechat na uživateli vyřešení nejednoznačnosti času.
Chcete-li nechat vyřešení nejednoznačnosti času na uživateli
Získejte datum a čas zadaný uživatelem.
Volejte metodu IsAmbiguousTime pro zjištění, zda je čas nejednoznačný.
Pokud je čas nejednoznačný, volejte metodu GetAmbiguousTimeOffsets pro získání pole objektů TimeSpan. Každý element pole obsahuje časový posun vzhledem k času UTC. Na tento posun může být nejednoznačný čas namapován.
Nechte uživateli vybrat požadovaný posun.
Získejte datum a čas UTC odečtením posunu zvoleného uživatelem od místního času.
Volejte metodu static (Shared v jazyce Visual Basic .NET) SpecifyKind pro nastavení hodnot vlastností data a času UTC Kind na DateTimeKind.Utc.
Příklad
Následující příklad vyzve uživatele k zadání data a času a pokud je nejednoznačný, nechá uživateli vybrat čas UTC, na který má být nejednoznačný čas namapován.
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
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("{0}.) {1} hours, {2} minutes", ctr, offsets[ctr].Hours, offsets[ctr].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("{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());
}
}
private DateTime GetUserDateTime()
{
bool exitFlag = false; // flag to exit loop if date is valid
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;
}
Základní část příkladu kódu používá pole objektů TimeSpan pro označení možných posunů nejednoznačného času od času UTC. Tyto posuny však pravděpodobně nebudou mít pro uživatele význam. Pro vysvětlení významu posunů, kód také popisuje, zda posunutí představuje standardní čas místního časového pásma nebo jeho letní čas. Kód určuje, který čas je standardní a který čas je letní porovnáním posunu s hodnotou vlastnosti BaseUtcOffset. Tato vlastnost označuje rozdíl mezi časem UTC a standardním časem časového pásma.
V tomto příkladu jsou všechny odkazy na místní časové pásmo provedeny pomocí vlastnosti TimeZoneInfo.Local. Místní časové pásmo není nikdy přiřazeno proměnné objektu. Toto je doporučenou praxí, protože volání metody TimeZoneInfo.ClearCachedData zruší platnost objektů, ke kterým je přiřazeno místní časové pásmo.
Probíhá kompilace kódu
Tento příklad vyžaduje:
Že bude do projektu přidán odkaz na System.Core.dll.
Že obor názvů System bude importován příkazem using (povinné v kódu jazyka C#).
Viz také
Úkoly
Postupy: Vyřešit nejednoznačné časy