System.DateTime-Struktur

Dieser Artikel enthält ergänzende Hinweise zur Referenzdokumentation für diese API.

Wichtig

Die Zeitrechnung in japanischen Kalendern basiert auf den Regierungsperioden der Kaiser und wird sich daher erwartungsgemäß ändern. Beispiel: Der 1. Mai 2019 markiert den Beginn des Reiwa-Zeitabschnitts in den Kalendern des Typs JapaneseCalendar und JapaneseLunisolarCalendar. Eine derartige Änderung der Zeitabschnitte betrifft alle Anwendungen, die diese Kalender verwenden. Weitere Informationen und informationen dazu, ob Ihre Anwendungen betroffen sind, finden Sie unter Behandeln einer neuen Ära im japanischen Kalender in .NET. Informationen zum Testen Ihrer Anwendungen auf Windows-Systemen, um ihre Bereitschaft für die Änderung der Ära sicherzustellen, finden Sie unter "Vorbereiten Ihrer Anwendung für die Änderung im japanischen Zeitalter". Features in .NET, die Kalender mit mehreren Epochen unterstützen und bewährte Methoden beim Arbeiten mit Kalendern, die mehrere Epochen unterstützen, finden Sie unter Arbeiten mit Eras.

Übersicht

Der DateTime Werttyp stellt Datums- und Uhrzeitangaben mit Werten zwischen 00:00:00 (Mitternacht), 1. Januar 0001 Anno Domini (Common Era) bis 11:59:59 Uhr, 31. Dezember 9999 A.D. (C.E.) im gregorianischen Kalender dar.

Zeitwerte werden in 100-Nanosekundeneinheiten gemessen, die als Teilstriche bezeichnet werden. Ein bestimmtes Datum ist die Anzahl der Teilstriche seit 12:00 Mitternacht, dem 1. Januar 0001 A.D. (C.E.) im GregorianCalendar Kalender. Die Zahl schließt Teilstriche aus, die durch Schaltsekunden hinzugefügt werden. Beispielsweise stellt ein Teilstrichwert von 3124137600000000L das Datum Freitag, 01. Januar 0100 12:00:00 Mitternacht dar. Ein DateTime Wert wird immer im Kontext eines expliziten oder Standardkalenders ausgedrückt.

Hinweis

Wenn Sie mit einem Teilstrichwert arbeiten, den Sie in ein anderes Zeitintervall konvertieren möchten, z. B. Minuten oder Sekunden, sollten Sie zum Ausführen der Konvertierung die TimeSpan.TicksPerDayKonvertierung verwenden. TimeSpan.TicksPerHourTimeSpan.TicksPerMinuteTimeSpan.TicksPerSecondTimeSpan.TicksPerMillisecond Wenn Sie beispielsweise der Komponente eines DateTime Werts die Anzahl von Sekunden hinzufügen möchten, die Second durch eine bestimmte Anzahl von Teilstrichen dargestellt werden, können Sie den Ausdruck dateValue.Second + nTicks/Timespan.TicksPerSecondverwenden.

Sie können die Quelle für den gesamten Satz von Beispielen aus diesem Artikel in Visual Basic, F# oder C# anzeigen.

Hinweis

Eine Alternative zur Struktur für das DateTime Arbeiten mit Datums- und Uhrzeitwerten in bestimmten Zeitzonen ist die DateTimeOffset Struktur. Die DateTimeOffset Struktur speichert Datums- und Uhrzeitinformationen in einem privaten DateTime Feld und die Anzahl der Minuten, mit denen sich dieses Datum und die Uhrzeit von UTC in einem privaten Int16 Feld unterscheiden. Dies ermöglicht es einer DateTimeOffset Wert entsprechend der die Zeit in einer bestimmten Zeitzone, während eine DateTime Wert kann nur UTC und der lokalen Zeitzone eindeutig darstellen. Eine Diskussion darüber, wann die DateTime Struktur oder struktur DateTimeOffset beim Arbeiten mit Datums- und Uhrzeitwerten verwendet werden soll, finden Sie unter "Auswählen zwischen DateTime", "DateTimeOffset", "TimeSpan" und "TimeZoneInfo".

Hinweis

Einige C#-Beispiele in diesem Artikel werden in der Inlinecodeausführung und dem Playground von Try.NET ausgeführt. Klicken Sie auf die Schaltfläche Ausführen, um ein Beispiel in einem interaktiven Fenster auszuführen. Nachdem Sie den Code ausgeführt haben, können Sie ihn ändern und den geänderten Code durch erneutes Anklicken der Schaltfläche Ausführen ausführen. Der geänderte Code wird entweder im interaktiven Fenster ausgeführt, oder das interaktive Fenster zeigt alle C#-Compilerfehlermeldungen an, wenn die Kompilierung fehlschlägt.

Die lokale Zeitzone der Inlinecodeausführung und dem Playground von Try.NET wird ist die Koordinierte Weltzeit (UTC). Dies kann sich auf das Verhalten und die Ausgabe von Beispielen auswirken, die die Typen DateTime, DateTimeOffset und TimeZoneInfo sowie deren Member veranschaulichen.

Dieser Artikel enthält mehrere Beispiele, die den DateTime Typ verwenden:

Initialisierungsbeispiele

Formatieren von DateTime Objekten als Beispiele für Zeichenfolgen

Analysieren von Zeichenfolgen als DateTime Beispiele für Objekte

DateTime Lösungsbeispiele

Beispiele für Kultur und Kalender

Persistenzbeispiele

Initialisieren eines DateTime-Objekts

Sie können einem neuen Wert auf vielfältige Weise einen neuen DateTime Wert zuweisen:

  • Aufrufen eines Konstruktors, entweder eines, in dem Sie Argumente für Werte angeben, oder den impliziten parameterlosen Konstruktor verwenden.
  • Zuweisen eines Werts DateTime zum Rückgabewert einer Eigenschaft oder Methode.
  • Analysieren eines DateTime Werts aus der Zeichenfolgendarstellung.
  • Verwenden von Visual Basic-spezifischen Sprachfeatures zum Instanziieren eines DateTime.

Die folgenden Codeausschnitte zeigen Beispiele für die einzelnen Codeausschnitte.

Aufrufen von Konstruktoren

Sie rufen eine der Überladungen des DateTime Konstruktors auf, die Elemente des Datums- und Uhrzeitwerts (z. B. Jahr, Monat und Tag oder die Anzahl der Teilstriche) angeben. Der folgende Code erstellt ein bestimmtes Datum mithilfe des DateTime Konstruktors, der das Jahr, den Monat, den Tag, die Stunde, die Minute und die Sekunde angibt.

Dim date1 As New Date(2008, 5, 1, 8, 30, 52)
var date1 = new DateTime(2008, 5, 1, 8, 30, 52);
Console.WriteLine(date1);
let date1 = DateTime(2008, 5, 1, 8, 30, 52)
printfn $"{date1}"

Sie rufen den impliziten parameterlosen Konstruktor der DateTime Struktur auf, wenn Ein Standardwert initialisiert werden soll DateTime . (Ausführliche Informationen zum impliziten parameterlosen Konstruktor eines Werttyps finden Sie unter Werttypen.) Einige Compiler unterstützen auch das Deklarieren eines DateTime Werts, ohne ihm explizit einen Wert zuzuweisen. Das Erstellen eines Werts ohne explizite Initialisierung führt auch zum Standardwert. Das folgende Beispiel veranschaulicht den DateTime impliziten parameterlosen Konstruktor in C# und Visual Basic sowie eine DateTime Deklaration ohne Zuweisung in Visual Basic.

Dim dat1 As DateTime
' The following method call displays 1/1/0001 12:00:00 AM.
Console.WriteLine(dat1.ToString(System.Globalization.CultureInfo.InvariantCulture))
' The following method call displays True.
Console.WriteLine(dat1.Equals(Date.MinValue))

Dim dat2 As New DateTime()
' The following method call displays 1/1/0001 12:00:00 AM.
Console.WriteLine(dat2.ToString(System.Globalization.CultureInfo.InvariantCulture))
' The following method call displays True.
Console.WriteLine(dat2.Equals(Date.MinValue))
var dat1 = new DateTime();
// The following method call displays 1/1/0001 12:00:00 AM.
Console.WriteLine(dat1.ToString(System.Globalization.CultureInfo.InvariantCulture));
// The following method call displays True.
Console.WriteLine(dat1.Equals(DateTime.MinValue));
let dat1 = DateTime()

// The following method call displays 1/1/0001 12:00:00 AM.
printfn $"{dat1.ToString System.Globalization.CultureInfo.InvariantCulture}"

// The following method call displays True.
printfn $"{dat1.Equals DateTime.MinValue}"

Zuweisen eines berechneten Werts

Sie können das Objekt einem Datums- und Uhrzeitwert zuweisen, der DateTime von einer Eigenschaft oder Methode zurückgegeben wird. Im folgenden Beispiel werden das aktuelle Datum und die aktuelle Uhrzeit, das aktuelle Utc-Datum (Coordinated Universal Time) und das aktuelle Datum drei neuen DateTime Variablen zugewiesen.

Dim date1 As Date = Date.Now
Dim date2 As Date = Date.UtcNow
Dim date3 As Date = Date.Today
DateTime date1 = DateTime.Now;
DateTime date2 = DateTime.UtcNow;
DateTime date3 = DateTime.Today;
let date1 = DateTime.Now
let date2 = DateTime.UtcNow
let date3 = DateTime.Today

Analysieren einer Zeichenfolge, die eine DateTime darstellt

Die ParseMethoden , ParseExact, TryParseund TryParseExact Methoden konvertieren eine Zeichenfolge in den entsprechenden Datums- und Uhrzeitwert. In den folgenden Beispielen werden die Parse und ParseExact die Methoden verwendet, um eine Zeichenfolge zu analysieren und in einen DateTime Wert zu konvertieren. Das zweite Format verwendet ein Formular, das vom ISO 8601-Standard für ein Datum und eine Uhrzeit im Zeichenfolgenformat unterstützt wird. Diese Standarddarstellung wird häufig verwendet, um Datumsinformationen in Webdiensten zu übertragen.

Dim dateString As String = "5/1/2008 8:30:52 AM"
Dim date1 As Date = Date.Parse(dateString,
                       System.Globalization.CultureInfo.InvariantCulture)
Dim iso8601String As String = "20080501T08:30:52Z"
Dim dateISO8602 As Date = DateTime.ParseExact(iso8601String, "yyyyMMddTHH:mm:ssZ",
                              System.Globalization.CultureInfo.InvariantCulture)
Console.WriteLine(dateISO8602)
var dateString = "5/1/2008 8:30:52 AM";
DateTime date1 = DateTime.Parse(dateString,
                          System.Globalization.CultureInfo.InvariantCulture);
var iso8601String = "20080501T08:30:52Z";
DateTime dateISO8602 = DateTime.ParseExact(iso8601String, "yyyyMMddTHH:mm:ssZ",
                                System.Globalization.CultureInfo.InvariantCulture);
let dateString = "5/1/2008 8:30:52 AM"
let date1 = DateTime.Parse(dateString, System.Globalization.CultureInfo.InvariantCulture)
let iso8601String = "20080501T08:30:52Z"
let dateISO8602 = DateTime.ParseExact(iso8601String, "yyyyMMddTHH:mm:ssZ", System.Globalization.CultureInfo.InvariantCulture)

Die TryParse Methoden geben TryParseExact an, ob es sich bei einer Zeichenfolge um eine gültige Darstellung eines DateTime Werts handelt und ggf. die Konvertierung durchführt.

Sprachspezifische Syntax für Visual Basic

Die folgende Visual Basic-Anweisung initialisiert einen neuen DateTime Wert.

Dim date1 As Date = #5/1/2008 8:30:52AM#

DateTime-Werte und deren Zeichenfolgendarstellungen

Intern werden alle DateTime Werte als Die Anzahl der Teilstriche (die Anzahl der Intervalle von 100-Nanosekunden) dargestellt, die seit 12:00:00 Mitternacht, dem 1. Januar 0001 verstrichen sind. Der tatsächliche DateTime Wert ist unabhängig von der Art und Weise, in der dieser Wert angezeigt wird, wenn er angezeigt wird. Das Erscheinungsbild eines DateTime Werts ist das Ergebnis eines Formatierungsvorgangs, der einen Wert in seine Zeichenfolgendarstellung konvertiert.

Das Aussehen von Datums- und Uhrzeitwerten hängt von Kultur, internationalen Standards, Anwendungsanforderungen und persönlichen Vorlieben ab. Die DateTime Struktur bietet Flexibilität beim Formatieren von Datums- und Uhrzeitwerten durch Überladungen von ToString. Die Standardmethode DateTime.ToString() gibt die Zeichenfolgendarstellung eines Datums- und Uhrzeitwerts mithilfe des kurzen Datums- und Zeitmusters der aktuellen Kultur zurück. Im folgenden Beispiel wird die Standardmethode DateTime.ToString() verwendet. Es zeigt das Datum und die Uhrzeit mithilfe des kurzen Datums- und Langen Zeitmusters für die aktuelle Kultur an. Die en-US-Kultur ist die aktuelle Kultur auf dem Computer, auf dem das Beispiel ausgeführt wurde.

var date1 = new DateTime(2008, 3, 1, 7, 0, 0);
Console.WriteLine(date1.ToString());
// For en-US culture, displays 3/1/2008 7:00:00 AM
let date1 = DateTime(2008, 3, 1, 7, 0, 0)
printfn $"{date1.ToString()}"
// For en-US culture, displays 3/1/2008 7:00:00 AM
Dim date1 As Date = #3/1/2008 7:00AM#
Console.WriteLine(date1.ToString())
' For en-US culture, displays 3/1/2008 7:00:00 AM

Möglicherweise müssen Sie Datumsangaben in einer bestimmten Kultur formatieren, um Webszenarien zu unterstützen, in denen sich der Server möglicherweise in einer anderen Kultur als der Client befindet. Sie geben die Kultur mithilfe der DateTime.ToString(IFormatProvider) Methode an, um die kurze Datums- und lange Zeitdarstellung in einer bestimmten Kultur zu erstellen. Im folgenden Beispiel wird die DateTime.ToString(IFormatProvider) Methode verwendet, um das Datum und die Uhrzeit mithilfe des kurzen Datums- und Langen Zeitmusters für die fr-FR-Kultur anzuzeigen.

var date1 = new DateTime(2008, 3, 1, 7, 0, 0);
Console.WriteLine(date1.ToString(System.Globalization.CultureInfo.CreateSpecificCulture("fr-FR")));
// Displays 01/03/2008 07:00:00
let date1 = DateTime(2008, 3, 1, 7, 0, 0)
printfn $"""{date1.ToString(System.Globalization.CultureInfo.CreateSpecificCulture "fr-FR")}"""
// Displays 01/03/2008 07:00:00
Dim date1 As Date = #3/1/2008 7:00AM#
Console.WriteLine(date1.ToString(System.Globalization.CultureInfo.CreateSpecificCulture("fr-FR")))
' Displays 01/03/2008 07:00:00

Andere Anwendungen erfordern möglicherweise unterschiedliche Zeichenfolgendarstellungen eines Datums. Die DateTime.ToString(String) Methode gibt die durch einen Standard- oder benutzerdefinierten Formatbezeichner definierte Zeichenfolgendarstellung mithilfe der Formatierungskonventionen der aktuellen Kultur zurück. Im folgenden Beispiel wird die DateTime.ToString(String) Methode verwendet, um das vollständige Datums- und Uhrzeitmuster für die en-US-Kultur, die aktuelle Kultur auf dem Computer anzuzeigen, auf dem das Beispiel ausgeführt wurde.

var date1 = new DateTime(2008, 3, 1, 7, 0, 0);
Console.WriteLine(date1.ToString("F"));
// Displays Saturday, March 01, 2008 7:00:00 AM
let date1 = DateTime(2008, 3, 1, 7, 0, 0)
printfn $"""{date1.ToString "F"}"""
// Displays Saturday, March 01, 2008 7:00:00 AM
Dim date1 As Date = #3/1/2008 7:00AM#
Console.WriteLine(date1.ToString("F"))
' Displays Saturday, March 01, 2008 7:00:00 AM

Schließlich können Sie sowohl die Kultur als auch das Format mithilfe der DateTime.ToString(String, IFormatProvider) Methode angeben. Im folgenden Beispiel wird die DateTime.ToString(String, IFormatProvider) Methode verwendet, um das vollständige Datums- und Uhrzeitmuster für die fr-FR-Kultur anzuzeigen.

var date1 = new DateTime(2008, 3, 1, 7, 0, 0);
Console.WriteLine(date1.ToString("F", new System.Globalization.CultureInfo("fr-FR")));
// Displays samedi 1 mars 2008 07:00:00
let date1 = DateTime(2008, 3, 1, 7, 0, 0)
printfn $"""{date1.ToString("F", new System.Globalization.CultureInfo "fr-FR")}"""
// Displays samedi 1 mars 2008 07:00:00
Dim date1 As Date = #3/1/2008 7:00AM#
Console.WriteLine(date1.ToString("F", New System.Globalization.CultureInfo("fr-FR")))
' Displays samedi 1 mars 2008 07:00:00

Die DateTime.ToString(String) Überladung kann auch mit einer benutzerdefinierten Formatzeichenfolge verwendet werden, um andere Formate anzugeben. Das folgende Beispiel zeigt, wie Sie eine Zeichenfolge mit dem ISO 8601-Standardformat formatieren, das häufig für Webdienste verwendet wird. Das Iso 8601-Format verfügt nicht über eine entsprechende Standardformatzeichenfolge.

var date1 = new DateTime(2008, 3, 1, 7, 0, 0, DateTimeKind.Utc);
Console.WriteLine(date1.ToString("yyyy-MM-ddTHH:mm:sszzz", System.Globalization.CultureInfo.InvariantCulture));
// Displays 2008-03-01T07:00:00+00:00
let date1 = DateTime(2008, 3, 1, 7, 0, 0, DateTimeKind.Utc)
printfn $"""{date1.ToString("yyyy-MM-ddTHH:mm:sszzz", System.Globalization.CultureInfo.InvariantCulture)}"""
// Displays 2008-03-01T07:00:00+00:00
Dim date1 As DateTime = New DateTime(2008, 3, 1, 7, 0, 0, DateTimeKind.Utc)
Console.WriteLine(date1.ToString("yyyy-MM-ddTHH:mm:sszzz", System.Globalization.CultureInfo.InvariantCulture))
' Displays 2008-03-01T07:00:00+00:00

Weitere Informationen zum Formatieren DateTime von Werten finden Sie unter Standard-Datums- und Uhrzeitformatzeichenfolgen sowie benutzerdefinierte Datums- und Uhrzeitformatzeichenfolgen.

Analysieren von DateTime-Werten aus Zeichenfolgen

Durch die Analyse wird die Zeichenfolgendarstellung eines Datums und einer Uhrzeit in einen DateTime Wert konvertiert. In der Regel weisen Datums- und Uhrzeitzeichenfolgen zwei unterschiedliche Verwendungen in Anwendungen auf:

  • Ein Datum und eine Uhrzeit nehmen eine Vielzahl von Formen und spiegeln die Konventionen der aktuellen Kultur oder einer bestimmten Kultur wider. Beispielsweise ermöglicht eine Anwendung einem Benutzer, dessen aktuelle Kultur en-US ist, einen Datumswert als "12.15.2013" oder "15. Dezember 2013" einzugeben. Damit kann ein Benutzer, dessen aktuelle Kultur en-gb ist, einen Datumswert als "15.12.2013" oder "15. Dezember 2013" eingeben.

  • Ein Datum und eine Uhrzeit werden in einem vordefinierten Format dargestellt. Beispielsweise serialisiert eine Anwendung ein Datum als "20130103" unabhängig von der Kultur, auf der die App ausgeführt wird. Eine Anwendung erfordert möglicherweise Datumsangaben, die im kurzen Datumsformat der aktuellen Kultur eingegeben werden.

Sie verwenden die Parse Oder-Methode TryParse , um eine Zeichenfolge aus einem der gängigen Datums- und Uhrzeitformate zu konvertieren, die von einer Kultur in einen DateTime Wert verwendet werden. Das folgende Beispiel zeigt, wie Sie Datumszeichenfolgen in verschiedenen kulturspezifischen Formaten in einen DateTime Wert konvertieren könnenTryParse. Sie ändert die aktuelle Kultur in Englisch (Vereinigtes Königreich) und ruft die GetDateTimeFormats() Methode auf, um ein Array von Datums- und Uhrzeitzeichenfolgen zu generieren. Anschließend wird jedes Element im Array an die TryParse Methode übergeben. Die Ausgabe aus dem Beispiel zeigt, dass die Analysemethode erfolgreich jede der kulturspezifischen Datums- und Uhrzeitzeichenfolgen konvertieren konnte.

System.Threading.Thread.CurrentThread.CurrentCulture =
    System.Globalization.CultureInfo.CreateSpecificCulture("en-GB");

var date1 = new DateTime(2013, 6, 1, 12, 32, 30);
var badFormats = new List<String>();

Console.WriteLine($"{"Date String",-37} {"Date",-19}\n");
foreach (var dateString in date1.GetDateTimeFormats())
{
    DateTime parsedDate;
    if (DateTime.TryParse(dateString, out parsedDate))
        Console.WriteLine($"{dateString,-37} {DateTime.Parse(dateString),-19}");
    else
        badFormats.Add(dateString);
}

// Display strings that could not be parsed.
if (badFormats.Count > 0)
{
    Console.WriteLine("\nStrings that could not be parsed: ");
    foreach (var badFormat in badFormats)
        Console.WriteLine($"   {badFormat}");
}
// Press "Run" to see the output.
System.Threading.Thread.CurrentThread.CurrentCulture <-
    System.Globalization.CultureInfo.CreateSpecificCulture "en-GB"

let date1 = DateTime(2013, 6, 1, 12, 32, 30)
let badFormats = ResizeArray<String>()

printfn "%-37s %-19s\n" "Date String" "Date"
for dateString in date1.GetDateTimeFormats() do
    match DateTime.TryParse dateString with
    | true, parsedDate ->
        printfn $"%-37s{dateString} %-19O{parsedDate}\n" 
    | _ ->
        badFormats.Add dateString

// Display strings that could not be parsed.
if badFormats.Count > 0 then
    printfn "\nStrings that could not be parsed: "
    for badFormat in badFormats do
        printfn $"   {badFormat}"
// Press "Run" to see the output.
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB")

Dim date1 As New DateTime(2013, 6, 1, 12, 32, 30)
Dim badFormats As New List(Of String)

Console.WriteLine($"{"Date String",-37} {"Date",-19}")
Console.WriteLine()
For Each dateString As String In date1.GetDateTimeFormats()
    Dim parsedDate As DateTime
    If DateTime.TryParse(dateString, parsedDate) Then
        Console.WriteLine($"{dateString,-37} {DateTime.Parse(dateString),-19:g}")
    Else
        badFormats.Add(dateString)
    End If
Next

' Display strings that could not be parsed.
If badFormats.Count > 0 Then
    Console.WriteLine()
    Console.WriteLine("Strings that could not be parsed: ")
    For Each badFormat In badFormats
        Console.WriteLine($"   {badFormat}")
    Next
End If
' The example displays the following output:
'       Date String                           Date               
'       
'       01/06/2013                            01/06/2013 00:00:00
'       01/06/13                              01/06/2013 00:00:00
'       1/6/13                                01/06/2013 00:00:00
'       1.6.13                                01/06/2013 00:00:00
'       2013-06-01                            01/06/2013 00:00:00
'       01 June 2013                          01/06/2013 00:00:00
'       1 June 2013                           01/06/2013 00:00:00
'       01 June 2013 12:32                    01/06/2013 12:32:00
'       01 June 2013 12:32                    01/06/2013 12:32:00
'       01 June 2013 12:32 PM                 01/06/2013 12:32:00
'       01 June 2013 12:32 PM                 01/06/2013 12:32:00
'       1 June 2013 12:32                     01/06/2013 12:32:00
'       1 June 2013 12:32                     01/06/2013 12:32:00
'       1 June 2013 12:32 PM                  01/06/2013 12:32:00
'       1 June 2013 12:32 PM                  01/06/2013 12:32:00
'       01 June 2013 12:32:30                 01/06/2013 12:32:30
'       01 June 2013 12:32:30                 01/06/2013 12:32:30
'       01 June 2013 12:32:30 PM              01/06/2013 12:32:30
'       01 June 2013 12:32:30 PM              01/06/2013 12:32:30
'       1 June 2013 12:32:30                  01/06/2013 12:32:30
'       1 June 2013 12:32:30                  01/06/2013 12:32:30
'       1 June 2013 12:32:30 PM               01/06/2013 12:32:30
'       1 June 2013 12:32:30 PM               01/06/2013 12:32:30
'       01/06/2013 12:32                      01/06/2013 12:32:00
'       01/06/2013 12:32                      01/06/2013 12:32:00
'       01/06/2013 12:32 PM                   01/06/2013 12:32:00
'       01/06/2013 12:32 PM                   01/06/2013 12:32:00
'       01/06/13 12:32                        01/06/2013 12:32:00
'       01/06/13 12:32                        01/06/2013 12:32:00
'       01/06/13 12:32 PM                     01/06/2013 12:32:00
'       01/06/13 12:32 PM                     01/06/2013 12:32:00
'       1/6/13 12:32                          01/06/2013 12:32:00
'       1/6/13 12:32                          01/06/2013 12:32:00
'       1/6/13 12:32 PM                       01/06/2013 12:32:00
'       1/6/13 12:32 PM                       01/06/2013 12:32:00
'       1.6.13 12:32                          01/06/2013 12:32:00
'       1.6.13 12:32                          01/06/2013 12:32:00
'       1.6.13 12:32 PM                       01/06/2013 12:32:00
'       1.6.13 12:32 PM                       01/06/2013 12:32:00
'       2013-06-01 12:32                      01/06/2013 12:32:00
'       2013-06-01 12:32                      01/06/2013 12:32:00
'       2013-06-01 12:32 PM                   01/06/2013 12:32:00
'       2013-06-01 12:32 PM                   01/06/2013 12:32:00
'       01/06/2013 12:32:30                   01/06/2013 12:32:30
'       01/06/2013 12:32:30                   01/06/2013 12:32:30
'       01/06/2013 12:32:30 PM                01/06/2013 12:32:30
'       01/06/2013 12:32:30 PM                01/06/2013 12:32:30
'       01/06/13 12:32:30                     01/06/2013 12:32:30
'       01/06/13 12:32:30                     01/06/2013 12:32:30
'       01/06/13 12:32:30 PM                  01/06/2013 12:32:30
'       01/06/13 12:32:30 PM                  01/06/2013 12:32:30
'       1/6/13 12:32:30                       01/06/2013 12:32:30
'       1/6/13 12:32:30                       01/06/2013 12:32:30
'       1/6/13 12:32:30 PM                    01/06/2013 12:32:30
'       1/6/13 12:32:30 PM                    01/06/2013 12:32:30
'       1.6.13 12:32:30                       01/06/2013 12:32:30
'       1.6.13 12:32:30                       01/06/2013 12:32:30
'       1.6.13 12:32:30 PM                    01/06/2013 12:32:30
'       1.6.13 12:32:30 PM                    01/06/2013 12:32:30
'       2013-06-01 12:32:30                   01/06/2013 12:32:30
'       2013-06-01 12:32:30                   01/06/2013 12:32:30
'       2013-06-01 12:32:30 PM                01/06/2013 12:32:30
'       2013-06-01 12:32:30 PM                01/06/2013 12:32:30
'       01 June                               01/06/2013 00:00:00
'       01 June                               01/06/2013 00:00:00
'       2013-06-01T12:32:30.0000000           01/06/2013 12:32:30
'       2013-06-01T12:32:30.0000000           01/06/2013 12:32:30
'       Sat, 01 Jun 2013 12:32:30 GMT         01/06/2013 05:32:30
'       Sat, 01 Jun 2013 12:32:30 GMT         01/06/2013 05:32:30
'       2013-06-01T12:32:30                   01/06/2013 12:32:30
'       12:32                                 22/04/2013 12:32:00
'       12:32                                 22/04/2013 12:32:00
'       12:32 PM                              22/04/2013 12:32:00
'       12:32 PM                              22/04/2013 12:32:00
'       12:32:30                              22/04/2013 12:32:30
'       12:32:30                              22/04/2013 12:32:30
'       12:32:30 PM                           22/04/2013 12:32:30
'       12:32:30 PM                           22/04/2013 12:32:30
'       2013-06-01 12:32:30Z                  01/06/2013 05:32:30
'       01 June 2013 19:32:30                 01/06/2013 19:32:30
'       01 June 2013 19:32:30                 01/06/2013 19:32:30
'       01 June 2013 07:32:30 PM              01/06/2013 19:32:30
'       01 June 2013 7:32:30 PM               01/06/2013 19:32:30
'       1 June 2013 19:32:30                  01/06/2013 19:32:30
'       1 June 2013 19:32:30                  01/06/2013 19:32:30
'       1 June 2013 07:32:30 PM               01/06/2013 19:32:30
'       1 June 2013 7:32:30 PM                01/06/2013 19:32:30
'       June 2013                             01/06/2013 00:00:00
'       June 2013                             01/06/2013 00:00:00

Sie verwenden die ParseExact Und TryParseExact Methoden, um eine Zeichenfolge zu konvertieren, die mit einem bestimmten Format oder Format in einen DateTime Wert übereinstimmen muss. Sie geben eine oder mehrere Datums- und Uhrzeitformatzeichenfolgen als Parameter für die Analysemethode an. Im folgenden Beispiel wird die TryParseExact(String, String[], IFormatProvider, DateTimeStyles, DateTime) Methode verwendet, um Zeichenfolgen zu konvertieren, die entweder im Format "yyyyyMMdd" oder im Format "HHmmss" in DateTime Werte vorliegen müssen.

string[] formats = { "yyyyMMdd", "HHmmss" };
string[] dateStrings = { "20130816", "20131608", "  20130816   ",
                   "115216", "521116", "  115216  " };
DateTime parsedDate;

foreach (var dateString in dateStrings)
{
    if (DateTime.TryParseExact(dateString, formats, null,
                               System.Globalization.DateTimeStyles.AllowWhiteSpaces |
                               System.Globalization.DateTimeStyles.AdjustToUniversal,
                               out parsedDate))
        Console.WriteLine($"{dateString} --> {parsedDate:g}");
    else
        Console.WriteLine($"Cannot convert {dateString}");
}
// The example displays the following output:
//       20130816 --> 8/16/2013 12:00 AM
//       Cannot convert 20131608
//         20130816    --> 8/16/2013 12:00 AM
//       115216 --> 4/22/2013 11:52 AM
//       Cannot convert 521116
//         115216   --> 4/22/2013 11:52 AM
let formats = [| "yyyyMMdd"; "HHmmss" |]
let dateStrings = 
    [ "20130816"; "20131608"; "  20130816   "
      "115216"; "521116"; "  115216  " ]

for dateString in dateStrings do
    match DateTime.TryParseExact(dateString, formats, null,
                                System.Globalization.DateTimeStyles.AllowWhiteSpaces |||
                                System.Globalization.DateTimeStyles.AdjustToUniversal) with
    | true, parsedDate ->
        printfn $"{dateString} --> {parsedDate:g}"
    | _ ->
        printfn $"Cannot convert {dateString}"

// The example displays the following output:
//       20130816 --> 8/16/2013 12:00 AM
//       Cannot convert 20131608
//         20130816    --> 8/16/2013 12:00 AM
//       115216 --> 4/22/2013 11:52 AM
//       Cannot convert 521116
//         115216   --> 4/22/2013 11:52 AM
Dim formats() As String = {"yyyyMMdd", "HHmmss"}
Dim dateStrings() As String = {"20130816", "20131608",
                              "  20130816   ", "115216",
                              "521116", "  115216  "}
Dim parsedDate As DateTime

For Each dateString As String In dateStrings
    If DateTime.TryParseExact(dateString, formats, Nothing,
                           DateTimeStyles.AllowWhiteSpaces Or
                           DateTimeStyles.AdjustToUniversal,
                           parsedDate) Then
        Console.WriteLine($"{dateString} --> {parsedDate:g}")
    Else
        Console.WriteLine($"Cannot convert {dateString}")
    End If
Next
' The example displays the following output:
'       20130816 --> 8/16/2013 12:00 AM
'       Cannot convert 20131608
'         20130816    --> 8/16/2013 12:00 AM
'       115216 --> 4/22/2013 11:52 AM
'       Cannot convert 521116
'         115216   --> 4/22/2013 11:52 AM

Eine häufige Verwendung besteht darin ParseExact , eine Zeichenfolgendarstellung aus einem Webdienst zu konvertieren, in der Regel im ISO 8601-Standardformat . Der folgende Code zeigt die richtige zu verwendende Formatzeichenfolge:

var iso8601String = "20080501T08:30:52Z";
DateTime dateISO8602 = DateTime.ParseExact(iso8601String, "yyyyMMddTHH:mm:ssZ",
    System.Globalization.CultureInfo.InvariantCulture);
Console.WriteLine($"{iso8601String} --> {dateISO8602:g}");
let iso8601String = "20080501T08:30:52Z"
let dateISO8602 = DateTime.ParseExact(iso8601String, "yyyyMMddTHH:mm:ssZ", System.Globalization.CultureInfo.InvariantCulture)

printfn $"{iso8601String} --> {dateISO8602:g}"
Dim iso8601String As String = "20080501T08:30:52Z"
Dim dateISO8602 As DateTime = DateTime.ParseExact(iso8601String, "yyyyMMddTHH:mm:ssZ", CultureInfo.InvariantCulture)
Console.WriteLine($"{iso8601String} --> {dateISO8602:g}")

Wenn eine Zeichenfolge nicht analysiert werden kann, lösen die Parse Methoden ParseExact eine Ausnahme aus. Die TryParse Methoden TryParseExact geben einen Boolean Wert zurück, der angibt, ob die Konvertierung erfolgreich war oder fehlgeschlagen ist. Sie sollten die Methoden oder TryParseExact Methoden TryParse in Szenarien verwenden, in denen die Leistung wichtig ist. Der Analysevorgang für Datums- und Uhrzeitzeichenfolgen weist tendenziell eine hohe Fehlerrate auf, und die Ausnahmebehandlung ist teuer. Verwenden Sie diese Methoden, wenn Zeichenfolgen von Benutzern eingegeben oder von einer unbekannten Quelle stammen.

Weitere Informationen zum Analysieren von Datums- und Uhrzeitwerten finden Sie unter Analysieren von Datums- und Uhrzeitzeichenfolgen.

DateTime-Werte

Beschreibungen von Zeitwerten im DateTime Typ werden häufig mithilfe des UTC-Standards (Coordinated Universal Time) ausgedrückt. Coordinated Universal Time ist der international anerkannte Name für Greenwich Mean Time (GMT). Koordinierte Weltzeit ist die Zeit, die bei null Grad Längengrad gemessen wird, dem UTC-Ursprungspunkt. Sommerzeit gilt nicht für UTC.

Die Ortszeit ist relativ zu einer bestimmten Zeitzone. Eine Zeitzone ist einem Zeitzonenoffset zugeordnet. Ein Zeitzonenoffset ist die Verschiebung der Zeitzone, die in Stunden vom UTC-Ursprungspunkt gemessen wird. Darüber hinaus wird die Ortszeit optional durch Sommerzeit beeinflusst, wodurch eine Zeitintervallanpassung addiert oder subtrahiert wird. Die Ortszeit wird berechnet, indem der Zeitzonenoffset zu UTC hinzugefügt und bei Bedarf für Sommerzeit angepasst wird. Der Zeitzonenoffset am UTC-Ursprungspunkt ist Null.

UTC-Zeit eignet sich für Berechnungen, Vergleiche und das Speichern von Datums- und Uhrzeitangaben in Dateien. Ortszeit eignet sich für die Anzeige in Benutzeroberflächen von Desktopanwendungen. Zeitzonenfähige Anwendungen (z. B. viele Webanwendungen) müssen auch mit einer Reihe anderer Zeitzonen arbeiten.

Wenn die Kind Eigenschaft eines DateTime Objekts lautet DateTimeKind.Unspecified, wird nicht angegeben, ob die dargestellte Zeit orts- oder UTC-Zeit oder eine Uhrzeit in einer anderen Zeitzone ist.

DateTime-Auflösung

Hinweis

Als Alternative zum Ausführen von Datums- und Uhrzeitarithmetik für DateTime Werte zum Messen der verstrichenen Zeit können Sie die Stopwatch Klasse verwenden.

Die Ticks Eigenschaft gibt Datums- und Uhrzeitwerte in Einheiten von einem Zehntel einer Sekunde an. Die Millisecond Eigenschaft gibt die Tausendstel einer Sekunde in einem Datums- und Uhrzeitwert zurück. Die Verwendung wiederholter Aufrufe der DateTime.Now Eigenschaft zum Messen der verstrichenen Zeit hängt von der Systemuhr ab. Die Systemuhr auf Windows 7- und Windows 8-Systemen hat eine Auflösung von ca. 15 Millisekunden. Diese Auflösung wirkt sich auf kleine Zeitintervalle unter 100 Millisekunden aus.

Im folgenden Beispiel wird die Abhängigkeit der aktuellen Datums- und Uhrzeitwerte zur Auflösung der Systemuhr veranschaulicht. Im Beispiel wiederholt eine äußere Schleife 20 Mal, und eine innere Schleife dient dazu, die äußere Schleife zu verzögern. Wenn der Wert des äußeren Schleifenzählers 10 ist, führt ein Aufruf der Thread.Sleep Methode eine Verzögerung von fünf Millisekunden ein. Das folgende Beispiel zeigt die Anzahl von Millisekunden, die von der DateTime.Now.Milliseconds Eigenschaft zurückgegeben werden, nur nach dem Aufruf von Thread.Sleep.

string output = "";
for (int ctr = 0; ctr <= 20; ctr++)
{
    output += String.Format($"{DateTime.Now.Millisecond}\n");
    // Introduce a delay loop.
    for (int delay = 0; delay <= 1000; delay++)
    { }

    if (ctr == 10)
    {
        output += "Thread.Sleep called...\n";
        System.Threading.Thread.Sleep(5);
    }
}
Console.WriteLine(output);
// Press "Run" to see the output.
let mutable output = ""
for i = 0 to 20 do
    output <- output + $"{DateTime.Now.Millisecond}\n"
    // Introduce a delay loop.
    for _ = 0 to 1000 do ()

    if i = 10 then
        output <- output + "Thread.Sleep called...\n"
        System.Threading.Thread.Sleep 5

printfn $"{output}"
// Press "Run" to see the output.
Dim output As String = ""
For ctr As Integer = 0 To 20
    output += Date.Now.Millisecond.ToString() + vbCrLf
    ' Introduce a delay loop.
    For delay As Integer = 0 To 1000
    Next

    If ctr = 10 Then
        output += "Thread.Sleep called..." + vbCrLf
        Thread.Sleep(5)
    End If
Next
Console.WriteLine(output)
' The example displays output like the following:
'       111
'       111
'       111
'       111
'       111
'       111
'       111
'       111
'       111
'       111
'       111
'       Thread.Sleep called...
'       143
'       143
'       143
'       143
'       143
'       143
'       143
'       143
'       143
'       143

DateTime-Vorgänge

Eine Berechnung, die eine DateTime Struktur verwendet, z Add . B. oder Subtract, ändert nicht den Wert der Struktur. Stattdessen gibt die Berechnung eine neue DateTime Struktur zurück, deren Wert das Ergebnis der Berechnung ist.

Konvertierungsvorgänge zwischen Zeitzonen (z. B. zwischen UTC und Ortszeit oder zwischen einer Zeitzone und einer anderen) berücksichtigen Sommerzeit, aber arithmetische und Vergleichsvorgänge nicht.

Die DateTime Struktur selbst bietet begrenzte Unterstützung für die Konvertierung von einer Zeitzone in eine andere. Sie können die ToLocalTime Methode verwenden, um UTC in Ortszeit zu konvertieren, oder Sie können die ToUniversalTime Methode verwenden, um von der lokalen Zeit in UTC zu konvertieren. Eine vollständige Gruppe von Zeitzonenkonvertierungsmethoden ist jedoch in der TimeZoneInfo Klasse verfügbar. Sie konvertieren die Uhrzeit in einer der Zeitzonen der Welt mit diesen Methoden in eine andere Zeitzone.

Berechnungen und Vergleiche von DateTime Objekten sind nur dann sinnvoll, wenn die Objekte Zeiten in derselben Zeitzone darstellen. Sie können ein TimeZoneInfo Objekt verwenden, um die Zeitzone eines DateTime Werts darzustellen, obwohl die beiden lose gekoppelt sind. Ein DateTime Objekt verfügt nicht über eine Eigenschaft, die ein Objekt zurückgibt, das die Zeitzone dieses Datums- und Uhrzeitwerts darstellt. Die Kind Eigenschaft gibt an, ob eine DateTime UTC- oder Ortszeit darstellt oder nicht angegeben ist. In einer zeitzonenfähigen Anwendung müssen Sie sich auf einen externen Mechanismus verlassen, um die Zeitzone zu bestimmen, in der ein DateTime Objekt erstellt wurde. Sie können eine Struktur verwenden, die sowohl den DateTime Wert als auch das TimeZoneInfo Objekt umschließt, das die DateTime Zeitzone des Werts darstellt. Ausführliche Informationen zur Verwendung von UTC in Berechnungen und Vergleichen mit DateTime Werten finden Sie unter Ausführen arithmetischer Vorgänge mit Datums- und Uhrzeitangaben.

Jedes DateTime Element verwendet implizit den gregorianischen Kalender, um seinen Vorgang auszuführen. Ausnahmen sind Methoden, die implizit einen Kalender angeben. Dazu gehören Konstruktoren, die einen Kalender angeben, und Methoden mit einem parameter abgeleitet von IFormatProvider, z System.Globalization.DateTimeFormatInfo. B. . .

Vorgänge nach Mitgliedern des DateTime Typs berücksichtigen Details wie Schaltjahre und die Anzahl der Tage in einem Monat.

DateTime-Werte und Kalender

Die .NET-Klassenbibliothek enthält eine Reihe von Kalenderklassen, die alle von der Calendar Klasse abgeleitet werden. Es sind:

Wichtig

Die Zeitrechnung in japanischen Kalendern basiert auf den Regierungsperioden der Kaiser und wird sich daher erwartungsgemäß ändern. Beispiel: Der 1. Mai 2019 markiert den Beginn des Reiwa-Zeitabschnitts in den Kalendern des Typs JapaneseCalendar und JapaneseLunisolarCalendar. Eine derartige Änderung der Zeitabschnitte betrifft alle Anwendungen, die diese Kalender verwenden. Weitere Informationen und informationen dazu, ob Ihre Anwendungen betroffen sind, finden Sie unter Behandeln einer neuen Ära im japanischen Kalender in .NET. Informationen zum Testen Ihrer Anwendungen auf Windows-Systemen, um ihre Bereitschaft für die Änderung der Ära sicherzustellen, finden Sie unter "Vorbereiten Ihrer Anwendung für die Änderung im japanischen Zeitalter". Features in .NET, die Kalender mit mehreren Epochen unterstützen und bewährte Methoden beim Arbeiten mit Kalendern, die mehrere Epochen unterstützen, finden Sie unter Arbeiten mit Eras.

Jede Kultur verwendet einen Standardkalender, der durch seine schreibgeschützte CultureInfo.Calendar Eigenschaft definiert ist. Jede Kultur kann einen oder mehrere Kalender unterstützen, die durch ihre schreibgeschützte CultureInfo.OptionalCalendars Eigenschaft definiert sind. Der aktuell von einem bestimmten CultureInfo Objekt verwendete Kalender wird durch seine DateTimeFormatInfo.Calendar Eigenschaft definiert. Es muss sich um einen der Kalender im CultureInfo.OptionalCalendars Array befinden.

Der aktuelle Kalender einer Kultur wird in allen Formatierungsvorgängen für diese Kultur verwendet. Der Standardkalender der thailändischen buddhistischen Kultur ist beispielsweise der Kalender der thailändischen buddhistischen Ära, der durch den ThaiBuddhistCalendar Kurs dargestellt wird. Wenn ein CultureInfo Objekt, das die thailändische buddhistische Kultur darstellt, in einem Datums- und Uhrzeitformatierungsvorgang verwendet wird, wird standardmäßig der Kalender der thailändischen buddhistischen Ära verwendet. Der gregorianische Kalender wird nur verwendet, wenn die Eigenschaft der DateTimeFormatInfo.Calendar Kultur geändert wird, wie im folgenden Beispiel gezeigt:

var thTH = new System.Globalization.CultureInfo("th-TH");
var value = new DateTime(2016, 5, 28);

Console.WriteLine(value.ToString(thTH));

thTH.DateTimeFormat.Calendar = new System.Globalization.GregorianCalendar();
Console.WriteLine(value.ToString(thTH));
// The example displays the following output:
//       28/5/2559 0:00:00
//       28/5/2016 0:00:00
let thTH = System.Globalization.CultureInfo "th-TH"
let value = DateTime(2016, 5, 28)

printfn $"{value.ToString thTH}"

thTH.DateTimeFormat.Calendar <- System.Globalization.GregorianCalendar()

printfn $"{value.ToString thTH}"

// The example displays the following output:
//       28/5/2559 0:00:00
//       28/5/2016 0:00:00
Dim thTH As New CultureInfo("th-TH")
Dim value As New DateTime(2016, 5, 28)

Console.WriteLine(value.ToString(thTH))

thTH.DateTimeFormat.Calendar = New GregorianCalendar()
Console.WriteLine(value.ToString(thTH))
' The example displays the following output:
'       28/5/2559 0:00:00
'       28/5/2016 0:00:00

Der aktuelle Kalender einer Kultur wird auch in allen Analysevorgängen für diese Kultur verwendet, wie im folgenden Beispiel gezeigt.

var thTH = new System.Globalization.CultureInfo("th-TH");
var value = DateTime.Parse("28/05/2559", thTH);
Console.WriteLine(value.ToString(thTH));

thTH.DateTimeFormat.Calendar = new System.Globalization.GregorianCalendar();
Console.WriteLine(value.ToString(thTH));
// The example displays the following output:
//       28/5/2559 0:00:00
//       28/5/2016 0:00:00
let thTH = System.Globalization.CultureInfo "th-TH"
let value = DateTime.Parse("28/05/2559", thTH)
printfn $"{value.ToString thTH}"

thTH.DateTimeFormat.Calendar <- System.Globalization.GregorianCalendar()
printfn $"{value.ToString thTH}"

// The example displays the following output:
//       28/5/2559 0:00:00
//       28/5/2016 0:00:00
Private Sub ThaiBuddhistEraParse()
    Dim thTH As New CultureInfo("th-TH")
    Dim value As DateTime = DateTime.Parse("28/5/2559", thTH)
    Console.WriteLine(value.ToString(thTH))

    thTH.DateTimeFormat.Calendar = New GregorianCalendar()
    Console.WriteLine(value.ToString(thTH))
    ' The example displays the following output:
    '       28/5/2559 0:00:00
    '       28/5/2016 0:00:00
End Sub

Sie instanziieren einen DateTime Wert mithilfe der Datums- und Uhrzeitelemente (Anzahl des Jahres, Monats und Tages) eines bestimmten Kalenders, indem Sie einen DateTime-Konstruktor aufrufen, der einen calendar Parameter enthält und ein Calendar Objekt übergibt, das diesen Kalender darstellt. Im folgenden Beispiel werden die Datums- und Uhrzeitelemente aus dem ThaiBuddhistCalendar Kalender verwendet.

var thTH = new System.Globalization.CultureInfo("th-TH");
var dat = new DateTime(2559, 5, 28, thTH.DateTimeFormat.Calendar);
Console.WriteLine($"Thai Buddhist era date: {dat.ToString("d", thTH)}");
Console.WriteLine($"Gregorian date:   {dat:d}");
// The example displays the following output:
//       Thai Buddhist Era Date:  28/5/2559
//       Gregorian Date:     28/05/2016
let thTH = System.Globalization.CultureInfo "th-TH"
let dat = DateTime(2559, 5, 28, thTH.DateTimeFormat.Calendar)

printfn $"""Thai Buddhist era date: {dat.ToString("d", thTH)}"""
printfn $"Gregorian date:   {dat:d}"

// The example displays the following output:
//       Thai Buddhist Era Date:  28/5/2559
//       Gregorian Date:     28/05/2016
Dim thTH As New CultureInfo("th-TH")
Dim dat As New DateTime(2559, 5, 28, thTH.DateTimeFormat.Calendar)
Console.WriteLine($"Thai Buddhist Era date: {dat.ToString("d", thTH)}")
Console.WriteLine($"Gregorian date:   {dat:d}")
' The example displays the following output:
'       Thai Buddhist Era Date:  28/5/2559
'       Gregorian Date:     28/05/2016

DateTime Konstruktoren, die keinen Parameter enthalten calendar , gehen davon aus, dass die Datums- und Uhrzeitelemente als Einheiten im gregorianischen Kalender ausgedrückt werden.

Alle anderen DateTime Eigenschaften und Methoden verwenden den gregorianischen Kalender. Beispielsweise gibt die DateTime.Year Eigenschaft das Jahr im gregorianischen Kalender zurück, und die DateTime.IsLeapYear(Int32) Methode geht davon aus, dass der year Parameter ein Jahr im gregorianischen Kalender ist. Jedes DateTime Mitglied, das den gregorianischen Kalender verwendet, verfügt über ein entsprechendes Element der Calendar Klasse, das einen bestimmten Kalender verwendet. Die Methode gibt beispielsweise Calendar.GetYear das Jahr in einem bestimmten Kalender zurück, und die Calendar.IsLeapYear Methode interpretiert den year Parameter als Jahreszahl in einem bestimmten Kalender. Im folgenden Beispiel werden sowohl die DateTime entsprechenden Member der Klasse als auch die entsprechenden Member der ThaiBuddhistCalendar Klasse verwendet.

var thTH = new System.Globalization.CultureInfo("th-TH");
var cal = thTH.DateTimeFormat.Calendar;
var dat = new DateTime(2559, 5, 28, cal);
Console.WriteLine("Using the Thai Buddhist Era calendar:");
Console.WriteLine($"Date: {dat.ToString("d", thTH)}");
Console.WriteLine($"Year: {cal.GetYear(dat)}");
Console.WriteLine($"Leap year: {cal.IsLeapYear(cal.GetYear(dat))}\n");

Console.WriteLine("Using the Gregorian calendar:");
Console.WriteLine($"Date: {dat:d}");
Console.WriteLine($"Year: {dat.Year}");
Console.WriteLine($"Leap year: {DateTime.IsLeapYear(dat.Year)}");
// The example displays the following output:
//       Using the Thai Buddhist Era calendar
//       Date :   28/5/2559
//       Year: 2559
//       Leap year :   True
//
//       Using the Gregorian calendar
//       Date :   28/05/2016
//       Year: 2016
//       Leap year :   True
let thTH = System.Globalization.CultureInfo "th-TH"
let cal = thTH.DateTimeFormat.Calendar
let dat = DateTime(2559, 5, 28, cal)
printfn "Using the Thai Buddhist Era calendar:"
printfn $"""Date: {dat.ToString("d", thTH)}"""
printfn $"Year: {cal.GetYear dat}"
printfn $"Leap year: {cal.IsLeapYear(cal.GetYear dat)}\n"

printfn "Using the Gregorian calendar:"
printfn $"Date: {dat:d}"
printfn $"Year: {dat.Year}"
printfn $"Leap year: {DateTime.IsLeapYear dat.Year}"

// The example displays the following output:
//       Using the Thai Buddhist Era calendar
//       Date :   28/5/2559
//       Year: 2559
//       Leap year :   True
//
//       Using the Gregorian calendar
//       Date :   28/05/2016
//       Year: 2016
//       Leap year :   True
Dim thTH As New CultureInfo("th-TH")
Dim cal As Calendar = thTH.DateTimeFormat.Calendar
Dim dat As New DateTime(2559, 5, 28, cal)
Console.WriteLine("Using the Thai Buddhist Era calendar:")
Console.WriteLine($"Date: {dat.ToString("d", thTH)}")
Console.WriteLine($"Year: {cal.GetYear(dat)}")
Console.WriteLine($"Leap year: {cal.IsLeapYear(cal.GetYear(dat))}")
Console.WriteLine()

Console.WriteLine("Using the Gregorian calendar:")
Console.WriteLine($"Date: {dat:d}")
Console.WriteLine($"Year: {dat.Year}")
Console.WriteLine($"Leap year: {DateTime.IsLeapYear(dat.Year)}")
' The example displays the following output:
'       Using the Thai Buddhist Era calendar
'       Date :   28/5/2559
'       Year: 2559
'       Leap year :   True
'
'       Using the Gregorian calendar
'       Date :   28/05/2016
'       Year: 2016
'       Leap year :   True

Die DateTime Struktur enthält eine DayOfWeek Eigenschaft, die den Wochentag im gregorianischen Kalender zurückgibt. Es enthält kein Mitglied, mit dem Sie die Wochennummer des Jahres abrufen können. Rufen Sie die Methode des einzelnen Kalenders Calendar.GetWeekOfYear auf, um die Woche des Jahres abzurufen. Dies wird im folgenden Beispiel veranschaulicht.

var thTH = new System.Globalization.CultureInfo("th-TH");
var thCalendar = thTH.DateTimeFormat.Calendar;
var dat = new DateTime(1395, 8, 18, thCalendar);
Console.WriteLine("Using the Thai Buddhist Era calendar:");
Console.WriteLine($"Date: {dat.ToString("d", thTH)}");
Console.WriteLine($"Day of Week: {thCalendar.GetDayOfWeek(dat)}");
Console.WriteLine($"Week of year: {thCalendar.GetWeekOfYear(dat, System.Globalization.CalendarWeekRule.FirstDay, DayOfWeek.Sunday)}\n");

var greg = new System.Globalization.GregorianCalendar();
Console.WriteLine("Using the Gregorian calendar:");
Console.WriteLine($"Date: {dat:d}");
Console.WriteLine($"Day of Week: {dat.DayOfWeek}");
Console.WriteLine($"Week of year: {greg.GetWeekOfYear(dat, System.Globalization.CalendarWeekRule.FirstDay,DayOfWeek.Sunday)}");
// The example displays the following output:
//       Using the Thai Buddhist Era calendar
//       Date :  18/8/1395
//       Day of Week: Sunday
//       Week of year: 34
//
//       Using the Gregorian calendar
//       Date :  18/08/0852
//       Day of Week: Sunday
//       Week of year: 34
let thTH = System.Globalization.CultureInfo "th-TH"
let thCalendar = thTH.DateTimeFormat.Calendar
let dat = DateTime(1395, 8, 18, thCalendar)
printfn "Using the Thai Buddhist Era calendar:"
printfn $"""Date: {dat.ToString("d", thTH)}"""
printfn $"Day of Week: {thCalendar.GetDayOfWeek dat}"
printfn $"Week of year: {thCalendar.GetWeekOfYear(dat, System.Globalization.CalendarWeekRule.FirstDay, DayOfWeek.Sunday)}\n"

let greg = System.Globalization.GregorianCalendar()
printfn "Using the Gregorian calendar:"
printfn $"Date: {dat:d}"
printfn $"Day of Week: {dat.DayOfWeek}"
printfn $"Week of year: {greg.GetWeekOfYear(dat, System.Globalization.CalendarWeekRule.FirstDay, DayOfWeek.Sunday)}"

// The example displays the following output:
//       Using the Thai Buddhist Era calendar
//       Date :  18/8/1395
//       Day of Week: Sunday
//       Week of year: 34
//
//       Using the Gregorian calendar
//       Date :  18/08/0852
//       Day of Week: Sunday
//       Week of year: 34
Dim thTH As New CultureInfo("th-TH")
Dim thCalendar As Calendar = thTH.DateTimeFormat.Calendar
Dim dat As New DateTime(1395, 8, 18, thCalendar)
Console.WriteLine("Using the Thai Buddhist Era calendar:")
Console.WriteLine($"Date: {dat.ToString("d", thTH)}")
Console.WriteLine($"Day of Week: {thCalendar.GetDayOfWeek(dat)}")
Console.WriteLine($"Week of year: {thCalendar.GetWeekOfYear(dat, CalendarWeekRule.FirstDay, DayOfWeek.Sunday)}")
Console.WriteLine()

Dim greg As Calendar = New GregorianCalendar()
Console.WriteLine("Using the Gregorian calendar:")
Console.WriteLine($"Date: {dat:d}")
Console.WriteLine($"Day of Week: {dat.DayOfWeek}")
Console.WriteLine($"Week of year: {greg.GetWeekOfYear(dat, CalendarWeekRule.FirstDay, DayOfWeek.Sunday)}")
' The example displays the following output:
'       Using the Thai Buddhist Era calendar
'       Date :  18/8/1395
'       Day of Week: Sunday
'       Week of year: 34
'       
'       Using the Gregorian calendar
'       Date :  18/08/0852
'       Day of Week: Sunday
'       Week of year: 34

Weitere Informationen zu Datumsangaben und Kalendern finden Sie unter Arbeiten mit Kalendern.

Persist DateTime-Werte

Sie können Werte auf folgende Weise beibehalten DateTime :

Sie müssen sicherstellen, dass die Routine, die die DateTime Werte wiederhergestellt, keine Daten verliert oder eine Ausnahme auslöst, unabhängig davon, welche Technik Sie auswählen. DateTime Werte sollten Roundtrips ausführen. Das heißt, der ursprüngliche Wert und der wiederhergestellte Wert sollten identisch sein. Und wenn der ursprüngliche DateTime Wert einen einzelnen Moment der Zeit darstellt, sollte er den gleichen Zeitpunkt identifizieren, in dem er wiederhergestellt wird.

Beibehalten von Werten als Zeichenfolgen

Um werte, die als Zeichenfolgen beibehalten werden, erfolgreich wiederherzustellen DateTime , befolgen Sie die folgenden Regeln:

  • Machen Sie dieselben Annahmen über kulturspezifische Formatierungen, wenn Sie die Zeichenfolge wiederherstellen, als wenn Sie sie beibehalten haben. Um sicherzustellen, dass eine Zeichenfolge auf einem System wiederhergestellt werden kann, dessen aktuelle Kultur sich von der Kultur des Systems unterscheidet, auf dem sie gespeichert wurde, rufen Sie die ToString Überladung auf, um die Zeichenfolge mithilfe der Konventionen der invarianten Kultur zu speichern. Rufen Sie die Parse(String, IFormatProvider, DateTimeStyles) Zeichenfolge mithilfe der Konventionen der invarianten Kultur auf, oder TryParse(String, IFormatProvider, DateTimeStyles, DateTime) rufen Sie die Überladung auf, um die Zeichenfolge wiederherzustellen. Verwenden Sie niemals die ToString(), Parse(String)oder TryParse(String, DateTime) Überladungen, die die Konventionen der aktuellen Kultur verwenden.

  • Wenn das Datum einen einzelnen Zeitmoment darstellt, stellen Sie sicher, dass es denselben Zeitpunkt darstellt, in dem es wiederhergestellt wird, auch in einer anderen Zeitzone. Konvertieren Sie den Wert vor dem Speichern oder Verwenden DateTimeOffsetin DateTime koordinierte Weltzeit (COORDINATED Universal Time, UTC).

Der häufigste Fehler beim Speichern von DateTime Werten als Zeichenfolgen besteht darin, die Formatierungskonventionen der Standard- oder aktuellen Kultur zu verwenden. Probleme treten auf, wenn sich die aktuelle Kultur beim Speichern und Wiederherstellen der Zeichenfolgen unterscheidet. Das folgende Beispiel veranschaulicht diese Probleme. Es speichert fünf Datumsangaben unter Verwendung der Formatierungskonventionen der aktuellen Kultur, die in diesem Fall Englisch (USA) ist. Sie stellt die Datumswerte mithilfe der Formatierungskonventionen einer anderen Kultur wieder her, die in diesem Fall Englisch (Vereinigtes Königreich) ist. Da die Formatierungskonventionen der beiden Kulturen unterschiedlich sind, können zwei der Datumsangaben nicht wiederhergestellt werden, und die neu Standard drei Datumsangaben werden falsch interpretiert. Wenn die ursprünglichen Datums- und Uhrzeitwerte einzelne Momente in der Zeit darstellen, sind die wiederhergestellten Zeiten falsch, da Zeitzoneninformationen verloren gehen.

public static void PersistAsLocalStrings()
{
    SaveLocalDatesAsString();
    RestoreLocalDatesFromString();
}

private static void SaveLocalDatesAsString()
{
    DateTime[] dates = { new DateTime(2014, 6, 14, 6, 32, 0),
                   new DateTime(2014, 7, 10, 23, 49, 0),
                   new DateTime(2015, 1, 10, 1, 16, 0),
                   new DateTime(2014, 12, 20, 21, 45, 0),
                   new DateTime(2014, 6, 2, 15, 14, 0) };
    string? output = null;

    Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}");
    Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:");
    for (int ctr = 0; ctr < dates.Length; ctr++)
    {
        Console.WriteLine(dates[ctr].ToString("f"));
        output += dates[ctr].ToString() + (ctr != dates.Length - 1 ? "|" : "");
    }
    var sw = new StreamWriter(filenameTxt);
    sw.Write(output);
    sw.Close();
    Console.WriteLine("Saved dates...");
}

private static void RestoreLocalDatesFromString()
{
    TimeZoneInfo.ClearCachedData();
    Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}");
    Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB");
    StreamReader sr = new StreamReader(filenameTxt);
    string[] inputValues = sr.ReadToEnd().Split(new char[] { '|' },
                                                StringSplitOptions.RemoveEmptyEntries);
    sr.Close();
    Console.WriteLine("The dates on an {0} system:",
                      Thread.CurrentThread.CurrentCulture.Name);
    foreach (var inputValue in inputValues)
    {
        DateTime dateValue;
        if (DateTime.TryParse(inputValue, out dateValue))
        {
            Console.WriteLine($"'{inputValue}' --> {dateValue:f}");
        }
        else
        {
            Console.WriteLine($"Cannot parse '{inputValue}'");
        }
    }
    Console.WriteLine("Restored dates...");
}
// When saved on an en-US system, the example displays the following output:
//       Current Time Zone: (UTC-08:00) Pacific Time (US & Canada)
//       The dates on an en-US system:
//       Saturday, June 14, 2014 6:32 AM
//       Thursday, July 10, 2014 11:49 PM
//       Saturday, January 10, 2015 1:16 AM
//       Saturday, December 20, 2014 9:45 PM
//       Monday, June 02, 2014 3:14 PM
//       Saved dates...
//
// When restored on an en-GB system, the example displays the following output:
//       Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London
//       The dates on an en-GB system:
//       Cannot parse //6/14/2014 6:32:00 AM//
//       //7/10/2014 11:49:00 PM// --> 07 October 2014 23:49
//       //1/10/2015 1:16:00 AM// --> 01 October 2015 01:16
//       Cannot parse //12/20/2014 9:45:00 PM//
//       //6/2/2014 3:14:00 PM// --> 06 February 2014 15:14
//       Restored dates...
let saveLocalDatesAsString () =
    let dates = 
        [ DateTime(2014, 6, 14, 6, 32, 0)
          DateTime(2014, 7, 10, 23, 49, 0)
          DateTime(2015, 1, 10, 1, 16, 0)
          DateTime(2014, 12, 20, 21, 45, 0)
          DateTime(2014, 6, 2, 15, 14, 0) ]

    printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"
    printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"

    let output =
        [ for date in dates do
            printfn $"{date}"
            string date ]
        |> String.concat "|"

    use sw = new StreamWriter(filenameTxt)
    sw.Write output
    printfn "Saved dates..."

let restoreLocalDatesFromString () =
    TimeZoneInfo.ClearCachedData()
    printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"
    Thread.CurrentThread.CurrentCulture <- CultureInfo.CreateSpecificCulture "en-GB"

    use sr = new StreamReader(filenameTxt)
    let inputValues = 
        sr.ReadToEnd().Split('|', StringSplitOptions.RemoveEmptyEntries)

    printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"

    for inputValue in inputValues do
        match DateTime.TryParse inputValue with
        | true, dateValue ->
            printfn $"'{inputValue}' --> {dateValue:f}"
        | _ ->
            printfn $"Cannot parse '{inputValue}'"

    printfn "Restored dates..."

let persistAsLocalStrings () =
    saveLocalDatesAsString ()
    restoreLocalDatesFromString ()

// When saved on an en-US system, the example displays the following output:
//       Current Time Zone: (UTC-08:00) Pacific Time (US & Canada)
//       The dates on an en-US system:
//       Saturday, June 14, 2014 6:32 AM
//       Thursday, July 10, 2014 11:49 PM
//       Saturday, January 10, 2015 1:16 AM
//       Saturday, December 20, 2014 9:45 PM
//       Monday, June 02, 2014 3:14 PM
//       Saved dates...
//
// When restored on an en-GB system, the example displays the following output:
//       Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London
//       The dates on an en-GB system:
//       Cannot parse //6/14/2014 6:32:00 AM//
//       //7/10/2014 11:49:00 PM// --> 07 October 2014 23:49
//       //1/10/2015 1:16:00 AM// --> 01 October 2015 01:16
//       Cannot parse //12/20/2014 9:45:00 PM//
//       //6/2/2014 3:14:00 PM// --> 06 February 2014 15:14
//       Restored dates...

Führen Sie die folgenden Schritte aus, um Die Werte für roundtrip erfolgreich auszuführen DateTime :

  1. Wenn die Werte einzelne Zeitmomente darstellen, konvertieren Sie sie von der lokalen Zeit in UTC, indem Sie die ToUniversalTime Methode aufrufen.
  2. Konvertieren Sie die Datumsangaben in ihre Zeichenfolgendarstellungen, indem Sie die ToString(String, IFormatProvider) Oder String.Format(IFormatProvider, String, Object[]) Überladung aufrufen. Verwenden Sie die Formatierungskonventionen der invarianten Kultur, indem Sie als provider Argument angebenCultureInfo.InvariantCulture. Geben Sie an, dass der Wert mithilfe der Standardformatzeichenfolge "O" oder "R" roundtripen soll.

Führen Sie die folgenden Schritte aus, um die dauerhaften DateTime Werte ohne Datenverlust wiederherzustellen:

  1. Analysieren Sie die Daten, indem Sie die ParseExact Daten aufrufen oder TryParseExact überladen. Geben Sie CultureInfo.InvariantCulture als provider Argument an, und verwenden Sie dieselbe Standardformatzeichenfolge, die Sie während der Konvertierung für das format Argument verwendet haben. Schließen Sie den DateTimeStyles.RoundtripKind Wert in das styles Argument ein.
  2. Wenn die DateTime Werte einzelne Momente in der Zeit darstellen, rufen Sie die ToLocalTime Methode auf, um das analysierte Datum von UTC in lokale Zeit zu konvertieren.

Im folgenden Beispiel wird die invariante Kultur und die Standardformatzeichenfolge "O" verwendet, um sicherzustellen, dass DateTime gespeicherte und wiederhergestellte Werte unabhängig vom System, der Kultur oder der Zeitzone der Quell- und Zielsysteme den gleichen Zeitpunkt darstellen.

public static void PersistAsInvariantStrings()
{
    SaveDatesAsInvariantStrings();
    RestoreDatesAsInvariantStrings();
}

private static void SaveDatesAsInvariantStrings()
{
    DateTime[] dates = { new DateTime(2014, 6, 14, 6, 32, 0),
                   new DateTime(2014, 7, 10, 23, 49, 0),
                   new DateTime(2015, 1, 10, 1, 16, 0),
                   new DateTime(2014, 12, 20, 21, 45, 0),
                   new DateTime(2014, 6, 2, 15, 14, 0) };
    string? output = null;

    Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}");
    Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:");
    for (int ctr = 0; ctr < dates.Length; ctr++)
    {
        Console.WriteLine(dates[ctr].ToString("f"));
        output += dates[ctr].ToUniversalTime().ToString("O", CultureInfo.InvariantCulture)
                  + (ctr != dates.Length - 1 ? "|" : "");
    }
    var sw = new StreamWriter(filenameTxt);
    sw.Write(output);
    sw.Close();
    Console.WriteLine("Saved dates...");
}

private static void RestoreDatesAsInvariantStrings()
{
    TimeZoneInfo.ClearCachedData();
    Console.WriteLine("Current Time Zone: {0}",
                      TimeZoneInfo.Local.DisplayName);
    Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB");
    StreamReader sr = new StreamReader(filenameTxt);
    string[] inputValues = sr.ReadToEnd().Split(new char[] { '|' },
                                                StringSplitOptions.RemoveEmptyEntries);
    sr.Close();
    Console.WriteLine("The dates on an {0} system:",
                      Thread.CurrentThread.CurrentCulture.Name);
    foreach (var inputValue in inputValues)
    {
        DateTime dateValue;
        if (DateTime.TryParseExact(inputValue, "O", CultureInfo.InvariantCulture,
                              DateTimeStyles.RoundtripKind, out dateValue))
        {
            Console.WriteLine($"'{inputValue}' --> {dateValue.ToLocalTime():f}");
        }
        else
        {
            Console.WriteLine("Cannot parse '{0}'", inputValue);
        }
    }
    Console.WriteLine("Restored dates...");
}
// When saved on an en-US system, the example displays the following output:
//       Current Time Zone: (UTC-08:00) Pacific Time (US & Canada)
//       The dates on an en-US system:
//       Saturday, June 14, 2014 6:32 AM
//       Thursday, July 10, 2014 11:49 PM
//       Saturday, January 10, 2015 1:16 AM
//       Saturday, December 20, 2014 9:45 PM
//       Monday, June 02, 2014 3:14 PM
//       Saved dates...
//
// When restored on an en-GB system, the example displays the following output:
//       Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London
//       The dates on an en-GB system:
//       '2014-06-14T13:32:00.0000000Z' --> 14 June 2014 14:32
//       '2014-07-11T06:49:00.0000000Z' --> 11 July 2014 07:49
//       '2015-01-10T09:16:00.0000000Z' --> 10 January 2015 09:16
//       '2014-12-21T05:45:00.0000000Z' --> 21 December 2014 05:45
//       '2014-06-02T22:14:00.0000000Z' --> 02 June 2014 23:14
//       Restored dates...
let saveDatesAsInvariantStrings () =
    let dates = 
        [ DateTime(2014, 6, 14, 6, 32, 0)
          DateTime(2014, 7, 10, 23, 49, 0)
          DateTime(2015, 1, 10, 1, 16, 0)
          DateTime(2014, 12, 20, 21, 45, 0)
          DateTime(2014, 6, 2, 15, 14, 0) ]

    printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"
    printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"

    let output =
        [ for date in dates do
            printfn $"{date:f}"
            date.ToUniversalTime().ToString("O", CultureInfo.InvariantCulture) ]
        |> String.concat "|"

    use sw = new StreamWriter(filenameTxt)
    sw.Write output
    printfn "Saved dates..."

let restoreDatesAsInvariantStrings () =
    TimeZoneInfo.ClearCachedData()
    printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"
    Thread.CurrentThread.CurrentCulture <- CultureInfo.CreateSpecificCulture "en-GB"
    
    use sr = new StreamReader(filenameTxt)
    let inputValues = 
        sr.ReadToEnd().Split('|', StringSplitOptions.RemoveEmptyEntries)

    printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"

    for inputValue in inputValues do
        match DateTime.TryParseExact(inputValue, "O", CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind) with
        | true, dateValue ->
            printfn $"'{inputValue}' --> {dateValue.ToLocalTime():f}"
        | _ ->
            printfn $"Cannot parse '{inputValue}'"

    printfn "Restored dates..."

let persistAsInvariantStrings () =
    saveDatesAsInvariantStrings ()
    restoreDatesAsInvariantStrings ()

// When saved on an en-US system, the example displays the following output:
//       Current Time Zone: (UTC-08:00) Pacific Time (US & Canada)
//       The dates on an en-US system:
//       Saturday, June 14, 2014 6:32 AM
//       Thursday, July 10, 2014 11:49 PM
//       Saturday, January 10, 2015 1:16 AM
//       Saturday, December 20, 2014 9:45 PM
//       Monday, June 02, 2014 3:14 PM
//       Saved dates...
//
// When restored on an en-GB system, the example displays the following output:
//       Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London
//       The dates on an en-GB system:
//       '2014-06-14T13:32:00.0000000Z' --> 14 June 2014 14:32
//       '2014-07-11T06:49:00.0000000Z' --> 11 July 2014 07:49
//       '2015-01-10T09:16:00.0000000Z' --> 10 January 2015 09:16
//       '2014-12-21T05:45:00.0000000Z' --> 21 December 2014 05:45
//       '2014-06-02T22:14:00.0000000Z' --> 02 June 2014 23:14
//       Restored dates...

Beibehalten von Werten als ganze Zahlen

Sie können ein Datum und eine Int64 Uhrzeit als Wert beibehalten, der eine Reihe von Teilstrichen darstellt. In diesem Fall müssen Sie nicht die Kultur der Systeme berücksichtigen, auf denen die DateTime Werte beibehalten und wiederhergestellt werden.

So speichern Sie einen DateTime Wert als ganze Zahl:

  1. Wenn die DateTime Werte einzelne Momente in der Zeit darstellen, konvertieren Sie sie durch Aufrufen der ToUniversalTime Methode in UTC.
  2. Rufen Sie die Anzahl der Teilstriche ab, die durch den DateTime Wert ihrer Ticks Eigenschaft dargestellt werden.

So stellen Sie einen DateTime Wert wieder her, der als ganze Zahl beibehalten wurde:

  1. Instanziieren Sie ein neues DateTime Objekt, indem Sie den Int64 Wert an den DateTime(Int64) Konstruktor übergeben.
  2. Wenn der DateTime Wert einen einzelnen Zeitpunkt darstellt, konvertieren Sie ihn von UTC in die lokale Zeit, indem Sie die ToLocalTime Methode aufrufen.

Im folgenden Beispiel wird ein Array von DateTime Werten als ganze Zahlen auf einem System in der Us-Pazifischen Zeitzone beibehalten. Es stellt es auf einem System in der UTC-Zone wieder her. Die Datei, die die ganzen Zahlen enthält, enthält einen Int32 Wert, der die Gesamtzahl der Int64 Werte angibt, die unmittelbar darauf folgen.

public static void PersistAsIntegers()
{
    SaveDatesAsInts();
    RestoreDatesAsInts();
}

private static void SaveDatesAsInts()
{
    DateTime[] dates = { new DateTime(2014, 6, 14, 6, 32, 0),
                   new DateTime(2014, 7, 10, 23, 49, 0),
                   new DateTime(2015, 1, 10, 1, 16, 0),
                   new DateTime(2014, 12, 20, 21, 45, 0),
                   new DateTime(2014, 6, 2, 15, 14, 0) };

    Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}");
    Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:");
    var ticks = new long[dates.Length];
    for (int ctr = 0; ctr < dates.Length; ctr++)
    {
        Console.WriteLine(dates[ctr].ToString("f"));
        ticks[ctr] = dates[ctr].ToUniversalTime().Ticks;
    }
    var fs = new FileStream(filenameInts, FileMode.Create);
    var bw = new BinaryWriter(fs);
    bw.Write(ticks.Length);
    foreach (var tick in ticks)
        bw.Write(tick);

    bw.Close();
    Console.WriteLine("Saved dates...");
}

private static void RestoreDatesAsInts()
{
    TimeZoneInfo.ClearCachedData();
    Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}");
    Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB");
    FileStream fs = new FileStream(filenameInts, FileMode.Open);
    BinaryReader br = new BinaryReader(fs);
    int items;
    DateTime[] dates;

    try
    {
        items = br.ReadInt32();
        dates = new DateTime[items];

        for (int ctr = 0; ctr < items; ctr++)
        {
            long ticks = br.ReadInt64();
            dates[ctr] = new DateTime(ticks).ToLocalTime();
        }
    }
    catch (EndOfStreamException)
    {
        Console.WriteLine("File corruption detected. Unable to restore data...");
        return;
    }
    catch (IOException)
    {
        Console.WriteLine("Unspecified I/O error. Unable to restore data...");
        return;
    }
    // Thrown during array initialization.
    catch (OutOfMemoryException)
    {
        Console.WriteLine("File corruption detected. Unable to restore data...");
        return;
    }
    finally
    {
        br.Close();
    }

    Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:");
    foreach (var value in dates)
        Console.WriteLine(value.ToString("f"));

    Console.WriteLine("Restored dates...");
}
// When saved on an en-US system, the example displays the following output:
//       Current Time Zone: (UTC-08:00) Pacific Time (US & Canada)
//       The dates on an en-US system:
//       Saturday, June 14, 2014 6:32 AM
//       Thursday, July 10, 2014 11:49 PM
//       Saturday, January 10, 2015 1:16 AM
//       Saturday, December 20, 2014 9:45 PM
//       Monday, June 02, 2014 3:14 PM
//       Saved dates...
//
// When restored on an en-GB system, the example displays the following output:
//       Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London
//       The dates on an en-GB system:
//       14 June 2014 14:32
//       11 July 2014 07:49
//       10 January 2015 09:16
//       21 December 2014 05:45
//       02 June 2014 23:14
//       Restored dates...
let saveDatesAsInts () =
    let dates = 
        [ DateTime(2014, 6, 14, 6, 32, 0)
          DateTime(2014, 7, 10, 23, 49, 0)
          DateTime(2015, 1, 10, 1, 16, 0)
          DateTime(2014, 12, 20, 21, 45, 0)
          DateTime(2014, 6, 2, 15, 14, 0) ]

    printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"
    printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"
    let ticks =
        [| for date in dates do
            printfn $"{date:f}"
            date.ToUniversalTime().Ticks |]
    use fs = new FileStream(filenameInts, FileMode.Create)
    use bw = new BinaryWriter(fs)
    bw.Write ticks.Length

    for tick in ticks do
        bw.Write tick

    printfn "Saved dates..."

let restoreDatesAsInts () =
    TimeZoneInfo.ClearCachedData()
    printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"
    Thread.CurrentThread.CurrentCulture <- CultureInfo.CreateSpecificCulture "en-GB"
    use fs = new FileStream(filenameInts, FileMode.Open)
    use br = new BinaryReader(fs)

    try
        let items = br.ReadInt32()
        let dates =
            [| for _ in 0..items do
                let ticks = br.ReadInt64()
                DateTime(ticks).ToLocalTime() |]

        printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"
        for value in dates do
            printfn $"{value:f}"
    with 
    | :? EndOfStreamException ->
        printfn "File corruption detected. Unable to restore data..."
    | :? IOException ->
        printfn "Unspecified I/O error. Unable to restore data..."
    // Thrown during array initialization.
    | :? OutOfMemoryException ->
        printfn"File corruption detected. Unable to restore data..."

    printfn "Restored dates..."

let persistAsIntegers () =
    saveDatesAsInts ()
    restoreDatesAsInts ()

// When saved on an en-US system, the example displays the following output:
//       Current Time Zone: (UTC-08:00) Pacific Time (US & Canada)
//       The dates on an en-US system:
//       Saturday, June 14, 2014 6:32 AM
//       Thursday, July 10, 2014 11:49 PM
//       Saturday, January 10, 2015 1:16 AM
//       Saturday, December 20, 2014 9:45 PM
//       Monday, June 02, 2014 3:14 PM
//       Saved dates...
//
// When restored on an en-GB system, the example displays the following output:
//       Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London
//       The dates on an en-GB system:
//       14 June 2014 14:32
//       11 July 2014 07:49
//       10 January 2015 09:16
//       21 December 2014 05:45
//       02 June 2014 23:14
//       Restored dates...

Serialisieren von DateTime-Werten

Sie können Werte durch Serialisierung in einen Datenstrom oder eine Datei beibehalten DateTime und dann durch Deserialisierung wiederherstellen. DateTime Daten werden in einem bestimmten Objektformat serialisiert. Die Objekte werden wiederhergestellt, wenn sie deserialisiert werden. Ein Formatierer oder Serialisierer( z JsonSerializerXmlSerializer. B. ) behandelt den Prozess der Serialisierung und Deserialisierung. Weitere Informationen zur Serialisierung und zu den von .NET unterstützten Serialisierungstypen finden Sie unter Serialisierung.

Im folgenden Beispiel wird die XmlSerializer Klasse zum Serialisieren und Deserialisieren DateTime von Werten verwendet. Die Werte stellen alle Schaltjahrtage im 20. Jahrhundert dar. Die Ausgabe stellt das Ergebnis dar, wenn das Beispiel auf einem System ausgeführt wird, dessen aktuelle Kultur Englisch (Vereinigtes Königreich) ist. Da Sie das DateTime Objekt selbst deserialisiert haben, muss der Code keine kulturellen Unterschiede in Datums- und Uhrzeitformaten behandeln.

public static void PersistAsXML()
{
    // Serialize the data.
    var leapYears = new List<DateTime>();
    for (int year = 2000; year <= 2100; year += 4)
    {
        if (DateTime.IsLeapYear(year))
            leapYears.Add(new DateTime(year, 2, 29));
    }
    DateTime[] dateArray = leapYears.ToArray();

    var serializer = new XmlSerializer(dateArray.GetType());
    TextWriter sw = new StreamWriter(filenameXml);

    try
    {
        serializer.Serialize(sw, dateArray);
    }
    catch (InvalidOperationException e)
    {
        Console.WriteLine(e.InnerException?.Message);
    }
    finally
    {
        if (sw != null) sw.Close();
    }

    // Deserialize the data.
    DateTime[]? deserializedDates;
    using (var fs = new FileStream(filenameXml, FileMode.Open))
    {
        deserializedDates = (DateTime[]?)serializer.Deserialize(fs);
    }

    // Display the dates.
    Console.WriteLine($"Leap year days from 2000-2100 on an {Thread.CurrentThread.CurrentCulture.Name} system:");
    int nItems = 0;
    if (deserializedDates is not null)
    {
        foreach (var dat in deserializedDates)
        {
            Console.Write($"   {dat:d}     ");
            nItems++;
            if (nItems % 5 == 0)
                Console.WriteLine();
        }
    }
}
// The example displays the following output:
//    Leap year days from 2000-2100 on an en-GB system:
//       29/02/2000       29/02/2004       29/02/2008       29/02/2012       29/02/2016
//       29/02/2020       29/02/2024       29/02/2028       29/02/2032       29/02/2036
//       29/02/2040       29/02/2044       29/02/2048       29/02/2052       29/02/2056
//       29/02/2060       29/02/2064       29/02/2068       29/02/2072       29/02/2076
//       29/02/2080       29/02/2084       29/02/2088       29/02/2092       29/02/2096
let persistAsXML () =
    // Serialize the data.
    let leapYears =
        [| for year in 2000..4..2100 do
            if DateTime.IsLeapYear year then
                DateTime(year, 2, 29) |]

    let serializer = XmlSerializer(leapYears.GetType())
    use sw = new StreamWriter(filenameXml)

    try
        serializer.Serialize(sw, leapYears)
    with :? InvalidOperationException as e ->
        printfn $"{e.InnerException.Message}"

    // Deserialize the data.
    use fs = new FileStream(filenameXml, FileMode.Open)
        
    let deserializedDates = serializer.Deserialize fs :?> DateTime []

    // Display the dates.
    printfn $"Leap year days from 2000-2100 on an {Thread.CurrentThread.CurrentCulture.Name} system:"
    
    let mutable nItems = 0
    for dat in deserializedDates do
        printf $"   {dat:d}     "
        nItems <- nItems + 1
        if nItems % 5 = 0 then
            printfn ""

// The example displays the following output:
//    Leap year days from 2000-2100 on an en-GB system:
//       29/02/2000       29/02/2004       29/02/2008       29/02/2012       29/02/2016
//       29/02/2020       29/02/2024       29/02/2028       29/02/2032       29/02/2036
//       29/02/2040       29/02/2044       29/02/2048       29/02/2052       29/02/2056
//       29/02/2060       29/02/2064       29/02/2068       29/02/2072       29/02/2076
//       29/02/2080       29/02/2084       29/02/2088       29/02/2092       29/02/2096

Das vorherige Beispiel enthält keine Zeitinformationen. Wenn ein DateTime Wert einen Moment in der Zeit darstellt und als lokale Zeit ausgedrückt wird, konvertieren Sie ihn von der lokalen Zeit in UTC, bevor sie durch Aufrufen der ToUniversalTime Methode serialisiert wird. Nachdem Sie sie deserialisiert haben, konvertieren Sie sie von UTC in lokale Zeit, indem Sie die ToLocalTime Methode aufrufen.

DateTime vs. TimeSpan

Die DateTime Typen und TimeSpan Werttypen unterscheiden sich darin, dass eine DateTime Instanz in der Zeit darstellt, während ein TimeSpan Zeitintervall darstellt. Sie können eine Instanz von DateTime einer anderen subtrahieren, um ein TimeSpan Objekt abzurufen, das das Zeitintervall zwischen ihnen darstellt. Alternativ können Sie dem aktuellen DateTime einen positiven TimeSpan Wert hinzufügen, um einen DateTime Wert abzurufen, der ein zukünftiges Datum darstellt.

Sie können ein Zeitintervall von einem DateTime Objekt addieren oder subtrahieren. Zeitintervalle können negativ oder positiv sein, und sie können in Einheiten wie Teilstrichen, Sekunden oder als TimeSpan Objekt ausgedrückt werden.

Vergleich der Gleichheit innerhalb der Toleranz

Gleichheitsvergleiche für DateTime Werte sind genau. Um gleich zu sein, müssen zwei Werte als dieselbe Anzahl von Teilstrichen ausgedrückt werden. Diese Genauigkeit ist für viele Anwendungen oft unnötig oder sogar falsch. Häufig möchten Sie testen, ob DateTime Objekte ungefähr gleich sind.

Im folgenden Beispiel wird veranschaulicht, wie ungefähr gleichwertige DateTime Werte verglichen werden. Sie akzeptiert einen kleinen Unterschiedsrand, wenn sie gleich deklariert werden.

public static bool RoughlyEquals(DateTime time, DateTime timeWithWindow, int windowInSeconds, int frequencyInSeconds)
{
    long delta = (long)((TimeSpan)(timeWithWindow - time)).TotalSeconds % frequencyInSeconds;
    delta = delta > windowInSeconds ? frequencyInSeconds - delta : delta;
    return Math.Abs(delta) < windowInSeconds;
}

public static void TestRoughlyEquals()
{
    int window = 10;
    int freq = 60 * 60 * 2; // 2 hours;

    DateTime d1 = DateTime.Now;

    DateTime d2 = d1.AddSeconds(2 * window);
    DateTime d3 = d1.AddSeconds(-2 * window);
    DateTime d4 = d1.AddSeconds(window / 2);
    DateTime d5 = d1.AddSeconds(-window / 2);

    DateTime d6 = (d1.AddHours(2)).AddSeconds(2 * window);
    DateTime d7 = (d1.AddHours(2)).AddSeconds(-2 * window);
    DateTime d8 = (d1.AddHours(2)).AddSeconds(window / 2);
    DateTime d9 = (d1.AddHours(2)).AddSeconds(-window / 2);

    Console.WriteLine($"d1 ({d1}) ~= d1 ({d1}): {RoughlyEquals(d1, d1, window, freq)}");
    Console.WriteLine($"d1 ({d1}) ~= d2 ({d2}): {RoughlyEquals(d1, d2, window, freq)}");
    Console.WriteLine($"d1 ({d1}) ~= d3 ({d3}): {RoughlyEquals(d1, d3, window, freq)}");
    Console.WriteLine($"d1 ({d1}) ~= d4 ({d4}): {RoughlyEquals(d1, d4, window, freq)}");
    Console.WriteLine($"d1 ({d1}) ~= d5 ({d5}): {RoughlyEquals(d1, d5, window, freq)}");

    Console.WriteLine($"d1 ({d1}) ~= d6 ({d6}): {RoughlyEquals(d1, d6, window, freq)}");
    Console.WriteLine($"d1 ({d1}) ~= d7 ({d7}): {RoughlyEquals(d1, d7, window, freq)}");
    Console.WriteLine($"d1 ({d1}) ~= d8 ({d8}): {RoughlyEquals(d1, d8, window, freq)}");
    Console.WriteLine($"d1 ({d1}) ~= d9 ({d9}): {RoughlyEquals(d1, d9, window, freq)}");
}
// The example displays output similar to the following:
//    d1 (1/28/2010 9:01:26 PM) ~= d1 (1/28/2010 9:01:26 PM): True
//    d1 (1/28/2010 9:01:26 PM) ~= d2 (1/28/2010 9:01:46 PM): False
//    d1 (1/28/2010 9:01:26 PM) ~= d3 (1/28/2010 9:01:06 PM): False
//    d1 (1/28/2010 9:01:26 PM) ~= d4 (1/28/2010 9:01:31 PM): True
//    d1 (1/28/2010 9:01:26 PM) ~= d5 (1/28/2010 9:01:21 PM): True
//    d1 (1/28/2010 9:01:26 PM) ~= d6 (1/28/2010 11:01:46 PM): False
//    d1 (1/28/2010 9:01:26 PM) ~= d7 (1/28/2010 11:01:06 PM): False
//    d1 (1/28/2010 9:01:26 PM) ~= d8 (1/28/2010 11:01:31 PM): True
//    d1 (1/28/2010 9:01:26 PM) ~= d9 (1/28/2010 11:01:21 PM): True
let roughlyEquals (time: DateTime) (timeWithWindow: DateTime) windowInSeconds frequencyInSeconds =
    let delta = 
        int64 (timeWithWindow - time).TotalSeconds % frequencyInSeconds
    
    let delta = if delta > windowInSeconds then frequencyInSeconds - delta else delta
    abs delta < windowInSeconds

let testRoughlyEquals () =
    let window = 10
    let window' = 10.
    let freq = 60 * 60 * 2 // 2 hours

    let d1 = DateTime.Now

    let d2 = d1.AddSeconds(2. * window')
    let d3 = d1.AddSeconds(-2. * window')
    let d4 = d1.AddSeconds(window' / 2.)
    let d5 = d1.AddSeconds(-window' / 2.)

    let d6 = (d1.AddHours 2).AddSeconds(2. * window')
    let d7 = (d1.AddHours 2).AddSeconds(-2. * window')
    let d8 = (d1.AddHours 2).AddSeconds(window' / 2.)
    let d9 = (d1.AddHours 2).AddSeconds(-window' / 2.)

    printfn $"d1 ({d1}) ~= d1 ({d1}): {roughlyEquals d1 d1 window freq}"
    printfn $"d1 ({d1}) ~= d2 ({d2}): {roughlyEquals d1 d2 window freq}"
    printfn $"d1 ({d1}) ~= d3 ({d3}): {roughlyEquals d1 d3 window freq}"
    printfn $"d1 ({d1}) ~= d4 ({d4}): {roughlyEquals d1 d4 window freq}"
    printfn $"d1 ({d1}) ~= d5 ({d5}): {roughlyEquals d1 d5 window freq}"

    printfn $"d1 ({d1}) ~= d6 ({d6}): {roughlyEquals d1 d6 window freq}"
    printfn $"d1 ({d1}) ~= d7 ({d7}): {roughlyEquals d1 d7 window freq}"
    printfn $"d1 ({d1}) ~= d8 ({d8}): {roughlyEquals d1 d8 window freq}"
    printfn $"d1 ({d1}) ~= d9 ({d9}): {roughlyEquals d1 d9 window freq}"

// The example displays output similar to the following:
//    d1 (1/28/2010 9:01:26 PM) ~= d1 (1/28/2010 9:01:26 PM): True
//    d1 (1/28/2010 9:01:26 PM) ~= d2 (1/28/2010 9:01:46 PM): False
//    d1 (1/28/2010 9:01:26 PM) ~= d3 (1/28/2010 9:01:06 PM): False
//    d1 (1/28/2010 9:01:26 PM) ~= d4 (1/28/2010 9:01:31 PM): True
//    d1 (1/28/2010 9:01:26 PM) ~= d5 (1/28/2010 9:01:21 PM): True
//    d1 (1/28/2010 9:01:26 PM) ~= d6 (1/28/2010 11:01:46 PM): False
//    d1 (1/28/2010 9:01:26 PM) ~= d7 (1/28/2010 11:01:06 PM): False
//    d1 (1/28/2010 9:01:26 PM) ~= d8 (1/28/2010 11:01:31 PM): True
//    d1 (1/28/2010 9:01:26 PM) ~= d9 (1/28/2010 11:01:21 PM): True
Public Shared Function RoughlyEquals(time As DateTime, timeWithWindow As DateTime,
                             windowInSeconds As Integer,
                             frequencyInSeconds As Integer) As Boolean
    Dim delta As Long = (timeWithWindow.Subtract(time)).TotalSeconds _
                                            Mod frequencyInSeconds

    If delta > windowInSeconds Then
        delta = frequencyInSeconds - delta
    End If

    Return Math.Abs(delta) < windowInSeconds
End Function

Public Shared Sub TestRoughlyEquals()
    Dim window As Integer = 10
    Dim freq As Integer = 60 * 60 * 2 ' 2 hours;
    Dim d1 As DateTime = DateTime.Now

    Dim d2 As DateTime = d1.AddSeconds(2 * window)
    Dim d3 As DateTime = d1.AddSeconds(-2 * window)
    Dim d4 As DateTime = d1.AddSeconds(window / 2)
    Dim d5 As DateTime = d1.AddSeconds(-window / 2)

    Dim d6 As DateTime = d1.AddHours(2).AddSeconds(2 * window)
    Dim d7 As DateTime = d1.AddHours(2).AddSeconds(-2 * window)
    Dim d8 As DateTime = d1.AddHours(2).AddSeconds(window / 2)
    Dim d9 As DateTime = d1.AddHours(2).AddSeconds(-window / 2)

    Console.WriteLine($"d1 ({d1}) ~= d1 ({d1}): {RoughlyEquals(d1, d1, window, freq)}")
    Console.WriteLine($"d1 ({d1}) ~= d2 ({d2}): {RoughlyEquals(d1, d2, window, freq)}")
    Console.WriteLine($"d1 ({d1}) ~= d3 ({d3}): {RoughlyEquals(d1, d3, window, freq)}")
    Console.WriteLine($"d1 ({d1}) ~= d4 ({d4}): {RoughlyEquals(d1, d4, window, freq)}")
    Console.WriteLine($"d1 ({d1}) ~= d5 ({d5}): {RoughlyEquals(d1, d5, window, freq)}")

    Console.WriteLine($"d1 ({d1}) ~= d6 ({d6}): {RoughlyEquals(d1, d6, window, freq)}")
    Console.WriteLine($"d1 ({d1}) ~= d7 ({d7}): {RoughlyEquals(d1, d7, window, freq)}")
    Console.WriteLine($"d1 ({d1}) ~= d8 ({d8}): {RoughlyEquals(d1, d8, window, freq)}")
    Console.WriteLine($"d1 ({d1}) ~= d9 ({d9}): {RoughlyEquals(d1, d9, window, freq)}")
End Sub
' The example displays output similar to the following:
'    d1 (1/28/2010 9:01:26 PM) ~= d1 (1/28/2010 9:01:26 PM): True
'    d1 (1/28/2010 9:01:26 PM) ~= d2 (1/28/2010 9:01:46 PM): False
'    d1 (1/28/2010 9:01:26 PM) ~= d3 (1/28/2010 9:01:06 PM): False
'    d1 (1/28/2010 9:01:26 PM) ~= d4 (1/28/2010 9:01:31 PM): True
'    d1 (1/28/2010 9:01:26 PM) ~= d5 (1/28/2010 9:01:21 PM): True
'    d1 (1/28/2010 9:01:26 PM) ~= d6 (1/28/2010 11:01:46 PM): False
'    d1 (1/28/2010 9:01:26 PM) ~= d7 (1/28/2010 11:01:06 PM): False
'    d1 (1/28/2010 9:01:26 PM) ~= d8 (1/28/2010 11:01:31 PM): True
'    d1 (1/28/2010 9:01:26 PM) ~= d9 (1/28/2010 11:01:21 PM): True

Überlegungen zur COM-Interoperabilität

Ein DateTime Wert, der an eine COM-Anwendung übertragen wird und dann zurück zu einer verwalteten Anwendung übertragen wird, wird als Roundtrip bezeichnet. Ein DateTime Wert, der nur eine Zeit angibt, führt jedoch nicht wie erwartet hin.

Wenn Sie nur eine Hin- und Rückfahrt durchführen, z. B. 13:00 Uhr, ist das Enddatum und die Endzeit der 30. Dezember 1899 C.E. um 3:00 Uhr statt am 1. Januar 0001 C.E. um 3:00 Uhr . NET und COM gehen von einem Standarddatum aus, wenn nur eine Uhrzeit angegeben wird. Das COM-System geht jedoch von einem Basisdatum vom 30. Dezember 1899 C.E. aus, während .NET von einem Basisdatum vom 1. Januar 0001 C.E ausgeht.

Wenn nur eine Zeit von .NET an COM übergeben wird, wird eine spezielle Verarbeitung ausgeführt, die die Zeit in das von COM verwendete Format konvertiert. Wenn nur eine Zeit von COM an .NET übergeben wird, wird keine spezielle Verarbeitung durchgeführt, da das legitime Datums- und Uhrzeitangaben am oder vor dem 30. Dezember 1899 beschädigt würde. Wenn ein Datum mit der Hin- und Rückreise von COM beginnt, behalten .NET und COM das Datum bei.

Das Verhalten von .NET und COM bedeutet, dass die Anwendung, wenn die Anwendung DateTime nur eine Zeit angibt, das datumsgerecht DateTime geändert oder ignoriert werden muss.