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
Lassen Sie das Datum und die Uhrzeit vom Benutzer eingeben.
Rufen Sie die IsAmbiguousTime-Methode auf, um festzustellen, ob die Zeit mehrdeutig ist.
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.
Lassen Sie den Benutzer den gewünschten Offset auswählen.
Ermitteln Sie das UTC-Datum und die UTC-Uhrzeit, indem Sie den vom Benutzer ausgewählten Offset von der Ortszeit abziehen.
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