Sdílet prostřednictvím


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

  1. Získejte datum a čas zadaný uživatelem.

  2. Volejte metodu IsAmbiguousTime pro zjištění, zda je čas nejednoznačný.

  3. 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.

  4. Nechte uživateli vybrat požadovaný posun.

  5. Získejte datum a čas UTC odečtením posunu zvoleného uživatelem od místního času.

  6. 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

Další zdroje

Data, časy a časových pásem