Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Dieser Artikel enthält ergänzende Hinweise zur Referenzdokumentation für diese API.
Wichtig
Ären in den japanischen Kalendern basieren auf der Herrschaft des Kaisers und werden daher voraussichtlich wechseln. Beispielsweise markierte der 1. Mai 2019 den Anfang der Reiwa-Ära in der JapaneseCalendar und JapaneseLunisolarCalendar. Eine solche Änderung des Zeitalters wirkt sich auf alle Anwendungen aus, die diese Kalender verwenden. Unter Handling a new era in the Japanese calendar in .NET (Umgang mit einem neuen Zeitabschnitt im japanischen Kalender in .NET) finden Sie weitere Informationen und wie Sie bestimmen können, ob Ihre Anwendungen ebenfalls betroffen sind. 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.
Überblick
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 Ticks bezeichnet werden. Ein bestimmtes Datum ist die Anzahl der Takte seit 00:00 Mitternacht, am 1. Januar 0001 n. Chr. im GregorianCalendar-Kalender. Die Zahl enthält keine Takte, die durch Schaltsekunden hinzugefügt werden. Der Taktwert „31241376000000000“ entspricht beispielsweise dem Datum Freitag, 01. Januar 0100, 00:00:00 (Mitternacht). Ein DateTime Wert wird immer im Kontext eines expliziten oder Standardkalenders ausgedrückt.
Hinweis
Wenn Sie mit einem Ticks-Wert arbeiten, den Sie in ein anderes Zeitintervall konvertieren möchten, z. B. Minuten oder Sekunden, sollten Sie die Konstanten TimeSpan.TicksPerDay, TimeSpan.TicksPerHour, TimeSpan.TicksPerMinute, TimeSpan.TicksPerSecond oder TimeSpan.TicksPerMillisecond für die Konvertierung verwenden. Wenn Sie beispielsweise der Second Komponente eines DateTime Werts die Anzahl von Sekunden hinzufügen möchten, die durch eine bestimmte Anzahl von Ticks dargestellt werden, können Sie den Ausdruck dateValue.Second + nTicks/Timespan.TicksPerSecond
verwenden.
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 einem DateTimeOffset Wert, die Uhrzeit in einer bestimmten Zeitzone widerzuspiegeln, während ein DateTime Wert nur UTC und die Zeit der lokalen Zeitzone eindeutig widerspiegeln kann. 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".
Quicklinks zu Beispielcode
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
- Aufrufen eines Konstruktors
- Aufrufen des impliziten parameterlosen Konstruktors
- Zuordnung aus Rückgabewert
- Analysieren einer Zeichenfolge, die ein Datum und eine Uhrzeit darstellt
- Visual Basic-Syntax zum Initialisieren eines Datums und einer Uhrzeit
Formatieren von DateTime
Objekten als Beispiele für Zeichenfolgen
- Verwenden des Standardmäßigen Datums-Uhrzeitformats
- Formatieren eines Datums und einer Uhrzeit mithilfe einer bestimmten Kultur
- Formatieren einer Datumszeit mithilfe einer Standard- oder benutzerdefinierten Formatzeichenfolge
- Angeben einer Formatzeichenfolge und einer bestimmten Kultur
- Formatieren einer Datumszeit mit dem ISO 8601-Standard für Webdienste
Parsen von Zeichenfolgen als DateTime
-Objektbeispiele
- Verwenden Sie
Parse
oderTryParse
, um eine Zeichenfolge in ein Datum und eine Uhrzeit zu konvertieren - Verwenden Sie
ParseExact
oderTryParseExact
, um eine Zeichenfolge in einen bekannten Format zu konvertieren - Konvertieren von der ISO 8601-Zeichenfolgendarstellung in ein Datum und eine Uhrzeit
DateTime
Lösungsbeispiele
- Erkunden der Auflösung von Datums- und Uhrzeitwerten
- Vergleich der Gleichheit innerhalb einer Toleranz
Beispiele für Kultur und Kalender
- Anzeigen von Datums- und Uhrzeitwerten mithilfe von kulturspezifischen Kalendern
- Analysieren von Zeichenfolgen gemäß einem kulturspezifischen Kalender
- Initialisieren eines Datums und einer Uhrzeit aus dem Kalender einer bestimmten Kultur
- Zugreifen auf Datums- und Uhrzeiteigenschaften mithilfe des Kalenders einer bestimmten Kultur
- Abrufen der Woche des Jahres mithilfe von kulturspezifischen Kalendern
Persistenzbeispiele
- Beibehalten von Datums- und Uhrzeitwerten als Zeichenfolgen in der lokalen Zeitzone
- Speichern von Datums- und Uhrzeitwerten als Zeichenfolgen in einem kultur- und zeitinvarianten Format
- Speichern von Datums- und Uhrzeitwerten als ganze Zahlen
- Beibehalten von Datums- und Uhrzeitwerten mithilfe der
XmlSerializer
Initialisieren eines DateTime-Objekts
Sie können einem neuen DateTime
Wert auf vielfältige Weise einen anfänglichen 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. - Instanziieren von
DateTime
mithilfe von Visual Basic-spezifischen Sprachfunktionen.
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 festlegen, wie zum Beispiel das Jahr, den Monat und den Tag oder die Anzahl der Ticks. 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 DateTime
auf seinen Standardwert initialisiert werden soll. (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 DateTime-Objekt einem Datums- und Uhrzeitwert zuweisen, der 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- und TryParseExact-Methoden geben an, ob eine Zeichenfolge eine gültige Darstellung eines DateTime-Werts ist und führen, falls ja, die Konvertierung durch.
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 Ticks (die Anzahl der Intervalle von 100-Nanosekunden) dargestellt, die seit 12:00 Uhr Mitternacht, dem 1. Januar 0001 verstrichen sind. Der tatsächliche DateTime Wert ist unabhängig davon, wie dieser Wert dargestellt 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 des langen Zeitmusters der aktuellen Kultur zurück. Im folgenden Beispiel wird die Standardmethode DateTime.ToString() verwendet. Sie zeigt das Datum und die Uhrzeit mit dem Muster für das kurze Datum und dem Muster für lange Zeit 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 erlaubt eine Anwendung einem Benutzer, dessen aktuelle Kultur en-US ist, einen Datumswert als "15.12.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 TryParse-Methode, um eine Zeichenfolge aus einem der gängigen von einer Kultur verwendeten Datums- und Uhrzeitformate in einen DateTime-Wert zu konvertieren. Das folgende Beispiel zeigt, wie Sie TryParse verwenden können, um Datumszeichenfolgen in verschiedenen kulturspezifischen Formaten in einen DateTime Wert zu konvertieren. Sie ändert die aktuelle Kultur auf 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, die mit einem bestimmten Format oder Formaten übereinstimmen muss, in einen DateTime Wert zu konvertieren. 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 von ParseExact besteht darin, 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, werfen die Parse und ParseExact Methoden eine Ausnahme. Die TryParse Methoden TryParseExact geben einen Boolean Wert zurück, der angibt, ob die Konvertierung erfolgreich war oder fehlgeschlagen ist. Sie sollten die Methoden TryParse oder TryParseExact 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 an die 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 an 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 mit einer DateTime-Struktur, z. B. Add 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, der von IFormatProvider abgeleitet ist, wie z. B. System.Globalization.DateTimeFormatInfo.
Vorgänge von Membern des DateTime-Typs berücksichtigen Details wie Schaltjahre und die Anzahl der Tage pro Monat.
DateTime-Werte und Kalender
Die .NET-Klassenbibliothek enthält eine Reihe von Kalenderklassen, die alle von der Calendar Klasse abgeleitet werden. Sie sind:
- Die ChineseLunisolarCalendar Klasse.
- Die EastAsianLunisolarCalendar Klasse.
- Die GregorianCalendar Klasse.
- Die HebrewCalendar Klasse.
- Die HijriCalendar Klasse.
- Die JapaneseCalendar Klasse.
- Die JapaneseLunisolarCalendar Klasse.
- Die JulianCalendar Klasse.
- Die KoreanCalendar Klasse.
- Die KoreanLunisolarCalendar Klasse.
- Die PersianCalendar Klasse.
- Die TaiwanCalendar Klasse.
- Die TaiwanLunisolarCalendar Klasse.
- Die ThaiBuddhistCalendar Klasse.
- Die UmAlQuraCalendar Klasse.
Wichtig
Ären in den japanischen Kalendern basieren auf der Herrschaft des Kaisers und werden daher voraussichtlich wechseln. Beispielsweise markierte der 1. Mai 2019 den Anfang der Reiwa-Ära in der JapaneseCalendar und JapaneseLunisolarCalendar. Eine solche Änderung des Zeitalters wirkt sich auf alle Anwendungen aus, die diese Kalender verwenden. Unter Handling a new era in the Japanese calendar in .NET (Umgang mit einem neuen Zeitabschnitt im japanischen Kalender in .NET) finden Sie weitere Informationen und wie Sie bestimmen können, ob Ihre Anwendungen ebenfalls betroffen sind. 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 jeweilige 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 einer der Kalender in der CultureInfo.OptionalCalendars Anordnung sein.
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 thailändisch-buddhistische Ära-Kalender, der durch die ThaiBuddhistCalendar Klasse 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 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 Member, 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.
Speichern von DateTime-Werten
Sie können Werte auf folgende Weise beibehalten DateTime :
- Konvertieren Sie sie in Zeichenfolgen , und speichern Sie die Zeichenfolgen.
- Konvertieren Sie sie in 64-Bit-Ganzzahlen (die Werte der Ticks-Eigenschaft), und speichern Sie die Ganzzahlen.
- Serialisieren Sie die DateTime-Werte.
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. Für DateTime-Werte sollte ein Roundtrip ausgeführt werden. 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.
Speichern von Werten als Zeichenfolgen
Um werte, die als Zeichenfolgen beibehalten werden, erfolgreich wiederherzustellen DateTime , befolgen Sie die folgenden Regeln:
Gehen Sie bei der Wiederherstellung der Zeichenfolge von denselben kulturspezifischen Formatierungen aus wie beim Speichern der Zeichenfolge. 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)- oder TryParse(String, IFormatProvider, DateTimeStyles, DateTime)-Überladung auf, um die Zeichenfolge gemäß den Konventionen der invarianten Kultur wiederherzustellen. Verwenden Sie niemals die Überladung ToString(), Parse(String) oder TryParse(String, DateTime), 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 DateTime-Wert vor dem Speichern in die koordinierte Weltzeit (Coordinated Universal Time, UTC), oder verwenden Sie DateTimeOffset.
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 verbleibenden 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 {Thread.CurrentThread.CurrentCulture.Name} system:");
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 einen erfolgreichen Roundtrip für DateTime-Werte auszuführen:
- Wenn die Werte einzelne Zeitmomente darstellen, konvertieren Sie sie von der lokalen Zeit in UTC, indem Sie die ToUniversalTime Methode aufrufen.
- Konvertieren Sie die Datumsangaben in ihre Zeichenfolgendarstellungen, indem Sie die Überladung ToString(String, IFormatProvider) oder String.Format(IFormatProvider, String, Object[]) aufrufen. Verwenden Sie die Formatierungskonventionen der invarianten Kultur, indem Sie CultureInfo.InvariantCulture als the
provider
Argument angeben. Geben Sie an, dass für den Wert mithilfe der Standardformatierungszeichenfolge „O“ oder „R“ ein Roundtrip ausgeführt werden soll.
Führen Sie die folgenden Schritte aus, um die dauerhaften DateTime Werte ohne Datenverlust wiederherzustellen:
- Parsen Sie die Daten, indem Sie die Überladung ParseExact oder TryParseExact aufrufen. Geben Sie CultureInfo.InvariantCulture als
provider
Argument an, und verwenden Sie dieselbe Standardformatzeichenfolge, die Sie während der Konvertierung für dasformat
Argument verwendet haben. Schließen Sie den DateTimeStyles.RoundtripKind Wert in dasstyles
Argument ein. - 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: {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 {Thread.CurrentThread.CurrentCulture.Name} system:");
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 '{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...
Speichern von Werten als ganze Zahlen
Sie können ein Datum und eine Uhrzeit als Int64-Wert speichern, der eine Anzahl von Takten 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:
- Wenn die DateTime Werte einzelne Momente in der Zeit darstellen, konvertieren Sie sie durch Aufrufen der ToUniversalTime Methode in UTC.
- Rufen Sie die Anzahl der Takte ab, die durch den DateTime-Wert der Ticks-Eigenschaft dargestellt werden.
So stellen Sie einen DateTime Wert wieder her, der als ganze Zahl beibehalten wurde:
- Instanziieren Sie ein neues DateTime Objekt, indem Sie den Int64 Wert an den DateTime(Int64) Konstruktor übergeben.
- 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 pazifischen Zeitzone der USA gespeichert. 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 DateTime Werte durch Serialisierung in einen Datenstrom oder eine Datei speichern 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, wie z. B. JsonSerializer oder XmlSerializer, 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 21. 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 TimeSpan einen positiven DateTime 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.
Gleichheitsüberprüfung innerhalb der Toleranz
Gleichheitsvergleiche für DateTime Werte sind genau. Um als gleich angesehen zu werden, müssen zwei Werte als dieselbe Anzahl von Ticks 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. Es wird eine kleine Abweichung akzeptiert, wenn sie als 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
COM-Interop-Überlegungen
Ein DateTime Wert, der an eine COM-Anwendung übertragen und dann zurück an eine verwaltete Anwendung übertragen wird, durchläuft einen sogenannten "Roundtrip". Für einen DateTime-Wert, der nur eine Uhrzeit angibt, wird jedoch nicht wie möglicherweise erwartet ein Roundtrip ausgeführt.
Wenn Sie einen Roundtrip nur für eine Zeitangabe ausführen, z. B. 15:00 Uhr, sind das endgültige Datum und die endgültige Uhrzeit 30. Dezember 1899 n. Chr., 15:00 Uhr statt 1. Januar 0001 n. Chr., 15: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 legitime Datums- und Uhrzeitangaben am oder vor dem 30. Dezember 1899 beschädigt würden. Wenn ein Datum seine Rundreise von COM aus beginnt, behalten .NET und COM das Datum bei.
Das Verhalten von .NET und COM bedeutet, dass, wenn Ihre Anwendung einen DateTime hin- und zurücküberträgt, der nur eine Zeit angibt, Ihre Anwendung daran denken muss, das fehlerhafte Datum des endgültigen DateTime-Objekts zu ändern oder zu ignorieren.