Vorgehensweise: Roundtrip-Datums- und -Uhrzeitwerte

In vielen Anwendungen soll ein Datums- und Uhrzeitwert einen bestimmten Zeitpunkt eindeutig identifizieren. In diesem Artikel wird gezeigt, wie ein DateTime-Wert, ein DateTimeOffset-Wert sowie ein Datums- und Uhrzeitwert mit Zeitzoneninformationen so gespeichert und wiederhergestellt werden, dass der wiederhergestellte Wert denselben Zeitpunkt bezeichnet wie der gespeicherte Wert.

Durchführen eines Roundtrips für einen DateTime-Wert

  1. Konvertieren Sie den DateTime-Wert in seine Zeichenfolgendarstellung, indem Sie die DateTime.ToString(String)-Methode mit dem Formatbezeichner „o“ aufrufen.

  2. Speichern Sie die Zeichenfolgendarstellung des DateTime-Werts in einer Datei, oder übergeben Sie sie über einen Prozess, eine Anwendungsdomäne oder eine Computergrenze.

  3. Rufen Sie die Zeichenfolge ab, die den DateTime-Wert darstellt.

  4. Rufen Sie die DateTime.Parse(String, IFormatProvider, DateTimeStyles)-Methode auf, und übergeben Sie DateTimeStyles.RoundtripKind als Wert für den styles-Parameter.

Das folgende Beispiel veranschaulicht, wie ein Roundtrip für einen DateTime-Wert ausgeführt wird.

const string fileName = @".\DateFile.txt";

StreamWriter outFile = new StreamWriter(fileName);

// Save DateTime value.
DateTime dateToSave = DateTime.SpecifyKind(new DateTime(2008, 6, 12, 18, 45, 15),
                                           DateTimeKind.Local);
string? dateString = dateToSave.ToString("o");
Console.WriteLine("Converted {0} ({1}) to {2}.",
                  dateToSave.ToString(),
                  dateToSave.Kind.ToString(),
                  dateString);
outFile.WriteLine(dateString);
Console.WriteLine("Wrote {0} to {1}.", dateString, fileName);
outFile.Close();

// Restore DateTime value.
DateTime restoredDate;

using StreamReader inFile = new StreamReader(fileName);
dateString = inFile.ReadLine();

if (dateString is not null)
{
    restoredDate = DateTime.Parse(dateString, null, DateTimeStyles.RoundtripKind);
    Console.WriteLine("Read {0} ({2}) from {1}.", restoredDate.ToString(),
                                                  fileName,
                                                  restoredDate.Kind.ToString());
}

// The example displays the following output:
//    Converted 6/12/2008 6:45:15 PM (Local) to 2008-06-12T18:45:15.0000000-05:00.
//    Wrote 2008-06-12T18:45:15.0000000-05:00 to .\DateFile.txt.
//    Read 6/12/2008 6:45:15 PM (Local) from .\DateFile.txt.
Const fileName As String = ".\DateFile.txt"

Dim outFile As New StreamWriter(fileName)

' Save DateTime value.
Dim dateToSave As Date = DateTime.SpecifyKind(#06/12/2008 6:45:15 PM#, _
                                              DateTimeKind.Local)
Dim dateString As String = dateToSave.ToString("o")
Console.WriteLine("Converted {0} ({1}) to {2}.", dateToSave.ToString(), _
                  dateToSave.Kind.ToString(), dateString)
outFile.WriteLine(dateString)
Console.WriteLine("Wrote {0} to {1}.", dateString, fileName)
outFile.Close()

' Restore DateTime value.
Dim restoredDate As Date

Dim inFile As New StreamReader(fileName)
dateString = inFile.ReadLine()
inFile.Close()
restoredDate = DateTime.Parse(dateString, Nothing, DateTimeStyles.RoundTripKind)
Console.WriteLine("Read {0} ({2}) from {1}.", restoredDate.ToString(), _
                  fileName, restoredDAte.Kind.ToString())
' The example displays the following output:
'    Converted 6/12/2008 6:45:15 PM (Local) to 2008-06-12T18:45:15.0000000-05:00.
'    Wrote 2008-06-12T18:45:15.0000000-05:00 to .\DateFile.txt.
'    Read 6/12/2008 6:45:15 PM (Local) from .\DateFile.txt.

Beim Ausführen von Roundtrips für einen DateTime-Wert wird durch diese Methode erfolgreich die Uhrzeit für alle Orts- und Weltzeiten beibehalten. Wenn beispielsweise ein lokaler DateTime-Wert auf einem System in der US-Zeitzone Pacific Standard Time gespeichert und auf einem System in der US-Zeitzone Central Standard Time wiederhergestellt wird, liegen das wiederhergestellte Datum und die Uhrzeit zwei Stunden hinter der ursprünglichen Zeit, was dem Zeitunterschied zwischen den beiden Zeitzonen entspricht. Dieses Verfahren ist für nicht spezifizierte Zeiten jedoch nicht notwendigerweise genau. Alle DateTime-Werte, deren Kind-Eigenschaft auf Unspecified festgelegt ist, werden als Ortszeiten behandelt. Wenn es sich nicht um die lokale Zeit handelt, kann der richtige Zeitpunkt durch DateTime nicht erfolgreich identifiziert werden. Die Umgehung für diese Einschränkung besteht darin, einen Datums- und Zeitwert für den Speicher- und Wiederherstellungsvorgang eng an die entsprechende Zeitzone zu koppeln.

Durchführen eines Roundtrips für einen DateTimeOffset-Wert

  1. Konvertieren Sie den DateTimeOffset-Wert in seine Zeichenfolgendarstellung, indem Sie die DateTimeOffset.ToString(String)-Methode mit dem Formatbezeichner „o“ aufrufen.

  2. Speichern Sie die Zeichenfolgendarstellung des DateTimeOffset-Werts in einer Datei, oder übergeben Sie sie über einen Prozess, eine Anwendungsdomäne oder eine Computergrenze.

  3. Rufen Sie die Zeichenfolge ab, die den DateTimeOffset-Wert darstellt.

  4. Rufen Sie die DateTimeOffset.Parse(String, IFormatProvider, DateTimeStyles)-Methode auf, und übergeben Sie DateTimeStyles.RoundtripKind als Wert für den styles-Parameter.

Das folgende Beispiel veranschaulicht, wie ein Roundtrip für einen DateTimeOffset-Wert ausgeführt wird.

const string fileName = @".\DateOff.txt";

StreamWriter outFile = new StreamWriter(fileName);

// Save DateTime value.
DateTimeOffset dateToSave = new DateTimeOffset(2008, 6, 12, 18, 45, 15,
                                               new TimeSpan(7, 0, 0));
string? dateString = dateToSave.ToString("o");
Console.WriteLine("Converted {0} to {1}.", dateToSave.ToString(),
                  dateString);
outFile.WriteLine(dateString);
Console.WriteLine("Wrote {0} to {1}.", dateString, fileName);
outFile.Close();

// Restore DateTime value.
DateTimeOffset restoredDateOff;

using StreamReader inFile = new StreamReader(fileName);
dateString = inFile.ReadLine();

if (dateString is not null)
{
    restoredDateOff = DateTimeOffset.Parse(dateString, null,
                                           DateTimeStyles.RoundtripKind);
    Console.WriteLine("Read {0} from {1}.", restoredDateOff.ToString(), fileName);
}

// The example displays the following output:
//    Converted 6/12/2008 6:45:15 PM +07:00 to 2008-06-12T18:45:15.0000000+07:00.
//    Wrote 2008-06-12T18:45:15.0000000+07:00 to .\DateOff.txt.
//    Read 6/12/2008 6:45:15 PM +07:00 from .\DateOff.txt.
Const fileName As String = ".\DateOff.txt"

Dim outFile As New StreamWriter(fileName)

' Save DateTime value.
Dim dateToSave As New DateTimeOffset(2008, 6, 12, 18, 45, 15, _
                                     New TimeSpan(7, 0, 0))
Dim dateString As String = dateToSave.ToString("o")
Console.WriteLine("Converted {0} to {1}.", dateToSave.ToString(), dateString)
outFile.WriteLine(dateString)
Console.WriteLine("Wrote {0} to {1}.", dateString, fileName)
outFile.Close()

' Restore DateTime value.
Dim restoredDateOff As DateTimeOffset

Dim inFile As New StreamReader(fileName)
dateString = inFile.ReadLine()
inFile.Close()
restoredDateOff = DateTimeOffset.Parse(dateString, Nothing, DateTimeStyles.RoundTripKind)
Console.WriteLine("Read {0} from {1}.", restoredDateOff.ToString(), fileName)
' The example displays the following output:
'    Converted 6/12/2008 6:45:15 PM +07:00 to 2008-06-12T18:45:15.0000000+07:00.
'    Wrote 2008-06-12T18:45:15.0000000+07:00 to .\DateOff.txt.
'    Read 6/12/2008 6:45:15 PM +07:00 from .\DateOff.txt.

Durch diese Methode wird ein DateTimeOffset-Wert immer eindeutig als ein einziger Zeitpunkt identifiziert. Der Wert kann dann durch Aufrufen der DateTimeOffset.ToUniversalTime-Methode in die koordinierte Weltzeit (UTC) oder durch Aufrufen der DateTimeOffset.ToOffset- oder TimeZoneInfo.ConvertTime(DateTimeOffset, TimeZoneInfo)-Methode in die Zeit einer bestimmten Zeitzone konvertiert werden. Die wesentliche Einschränkung dieser Methode liegt darin, dass die Datums- und Uhrzeitarithmetik möglicherweise keine genauen Ergebnisse für die jeweilige Zeitzone liefert, wenn sie bei einem DateTimeOffset-Wert durchgeführt wird, der die Zeit in einer bestimmten Zeitzone darstellt. Grund hierfür ist, dass die Zuordnung eines DateTimeOffset-Werts zu seiner Zeitzone bei seiner Instanziierung aufgehoben wird. Daher können die Anpassungsregeln für diese Zeitzone bei Datums- und Uhrzeitberechnungen nicht mehr angewendet werden. Sie können dieses Problem umgehen, indem Sie einen benutzerdefinierten Typ definieren, der sowohl einen Datums- und Uhrzeitwert als auch die dazugehörige Zeitzone enthält.

Kompilieren des Codes

Diese Beispiele erfordern, dass die folgenden Namespaces mit C# using-Direktiven oder Visual Basic Imports-Anweisungen importiert werden:

Siehe auch