Freigeben über


Gewusst wie: Auflösen mehrdeutiger Zeiten durch den Benutzer

Bei einer mehrdeutigen Zeit handelt es sich um eine Zeit, die mehreren koordinierten Weltzeiten (Coordinated Universal Time; UTC) zugeordnet ist. Sie tritt auf, wenn die Uhrzeit zurückgestellt wird, beispielsweise bei der Umstellung von der Sommerzeit in einer Zeitzone auf die Standardzeit. Bei der Behandlung einer mehrdeutigen Zeit können Sie wie folgt vorgehen:

  • Wenn die mehrdeutige Zeit vom Benutzer eingegeben wurde, können Sie dem Benutzer die Auslösung der Mehrdeutigkeit überlassen.

  • Treffen Sie eine Annahme darüber, wie die Zeit UTC zugeordnet ist. Sie können zum Beispiel annehmen, dass eine mehrdeutige Zeit immer als Standardzeit der Zeitzone ausgedrückt wird.

In diesem Thema wird erläutert, wie Sie einen Benutzer eine mehrdeutige Zeit auflösen lassen.

So lassen Sie einen Benutzer eine mehrdeutige Zeit auflösen

  1. Lassen Sie das Datum und die Uhrzeit vom Benutzer eingeben.

  2. Rufen Sie die IsAmbiguousTime-Methode auf, um festzustellen, ob die Zeit mehrdeutig ist.

  3. Wenn die Zeit mehrdeutig ist, rufen Sie die GetAmbiguousTimeOffsets-Methode auf, um ein Array von TimeSpan-Objekten abzurufen. Jedes Element im Array enthält einen UTC-Offset, dem die mehrdeutige Zeit zugeordnet werden kann.

  4. Lassen Sie den Benutzer den gewünschten Offset auswählen.

  5. Ermitteln Sie das UTC-Datum und die UTC-Uhrzeit, indem Sie den vom Benutzer ausgewählten Offset von der Ortszeit abziehen.

  6. Rufen Sie die static (Shared in Visual Basic .NET) SpecifyKind-Methode auf, um für die Kind-Eigenschaft des UTC-Datums und der UTC-Uhrzeit den Wert DateTimeKind.Utc festzulegen.

Beispiel

Im folgenden Beispiel wird der Benutzer zur Eingabe eines Datums und einer Uhrzeit aufgefordert. Wenn diese nicht eindeutig sind, kann der Benutzer die UTC-Zeit auswählen, die der mehrdeutigen Zeit zugeordnet ist.

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;        
}

Der Kern des Beispielcodes verwendet ein Array von TimeSpan-Objekten, um mögliche Offsets der mehrdeutigen Zeit von UTC anzugeben. Die Bedeutung dieser Offsets ist für den Benutzer wahrscheinlich jedoch nicht ersichtlich. Um die Bedeutung der Offsets klarzustellen, gibt der Code auch an, ob ein Offset die Normalzeit der lokalen Zeitzone darstellt oder die entsprechende Sommerzeit. Der Code ermittelt, welche Zeit die Normalzeit und welche die Sommerzeit ist, indem der Offset mit dem Wert der BaseUtcOffset-Eigenschaft verglichen wird. Diese Eigenschaft gibt den Unterschied zwischen UTC und der Normalzeit der Zeitzone an.

In diesem Beispiel erfolgen alle Verweise auf die lokale Zeitzone über die TimeZoneInfo.Local-Eigenschaft, und die lokale Zeitzone ist nie einer Objektvariablen zugewiesen. Hierbei handelt es sich um eine empfohlene Vorgehensweise, da durch einen Aufruf der TimeZoneInfo.ClearCachedData-Methode alle Objekte, denen die lokale Zeitzone zugewiesen ist, ungültig werden.

Kompilieren des Codes

Für dieses Beispiel ist Folgendes erforderlich:

  • Dem Projekt muss ein Verweis auf System.Core.dll hinzugefügt werden.

  • Der System-Namespace muss mit der using-Anweisung (in C#-Code erforderlich) importiert werden.

Siehe auch

Aufgaben

Gewusst wie: Auflösen von mehrdeutigen Zeiten

Weitere Ressourcen

Datumsangaben, Uhrzeiten und Zeitzonen