System.DateTime – struktura
Tento článek obsahuje doplňující poznámky k referenční dokumentaci pro toto rozhraní API.
Důležité
Éry v japonských kalendářích jsou založeny na vládě císaře, a proto se očekává, že se změní. Například 1. května 2019 označil začátek období Reiwa v roce 2019 a JapaneseCalendarJapaneseLunisolarCalendar. Taková změna éry ovlivňuje všechny aplikace, které tyto kalendáře používají. Další informace a určení, zda jsou ovlivněny vaše aplikace, naleznete v tématu Zpracování nové éry v japonském kalendáři v .NET. Informace o testování aplikací v systémech Windows za účelem zajištění připravenosti na změnu v éře najdete v tématu Příprava aplikace na změnu japonské éry. Funkce v .NET, které podporují kalendáře s více obdobími a osvědčené postupy při práci s kalendáři, které podporují více období, najdete v tématu Práce s obdobími.
Přehled
Typ DateTime hodnoty představuje kalendářní data a časy s hodnotami v rozmezí od 00:00:00 (půlnoc), 1. ledna 0001 Anno Domini (Společná éra) až 11:59:59,31. prosince 9999 A.D. (C.E.) v gregoriánském kalendáři.
Časové hodnoty se měří v 100 nanosekundových jednotkách nazývaných ticks. Konkrétní datum je počet od 12:00 půlnoci, 1. ledna 0001 A.D. (C.E.) v GregorianCalendar kalendáři. Číslo vyloučí záškrty, které by se přidaly přestupnými sekundami. Například hodnota ticks 3124137600000000L představuje datum pátek, leden 01, 0100 12:00:00 půlnoc. DateTime Hodnota se vždy vyjadřuje v kontextu explicitního nebo výchozího kalendáře.
Poznámka:
Pokud pracujete s hodnotou záškrtů, kterou chcete převést na jiný časový interval, například minuty nebo sekundy, měli byste k provedení převodu použít hodnotu TimeSpan.TicksPerDay, TimeSpan.TicksPerHour, TimeSpan.TicksPerMinute, TimeSpan.TicksPerSecondnebo TimeSpan.TicksPerMillisecond konstantu. Chcete-li například přidat počet sekund reprezentovaných zadaným počtem záškrtů do Second součásti DateTime hodnoty, můžete použít výraz dateValue.Second + nTicks/Timespan.TicksPerSecond
.
Zdroj pro celou sadu příkladů z tohoto článku si můžete prohlédnout v jazyce Visual Basic, F# nebo C#.
Poznámka:
Alternativou ke DateTime struktuře pro práci s hodnotami data a času v konkrétních časových pásmech je DateTimeOffset struktura. Struktura DateTimeOffset ukládá informace o datu a čase v privátním DateTime poli a počet minut, o které se toto datum a čas liší od času UTC v privátním Int16 poli. To umožňuje DateTimeOffset , aby hodnota odrážela čas v určitém časovém pásmu, zatímco DateTime hodnota může jednoznačně odrážet pouze UTC a čas místního časového pásma. Diskuzi o tom, kdy použít DateTime strukturu nebo DateTimeOffset strukturu při práci s hodnotami data a času, naleznete v tématu Volba Mezi DateTime, DateTimeOffset, TimeSpan a TimeZoneInfo.
Rychlé odkazy na ukázkový kód
Poznámka:
Některé příklady jazyka C# v tomto článku se spouštějí v Try.NET inline code runner a playground. Vyberte tlačítko Spustit a spusťte příklad v interaktivním okně. Jakmile kód spustíte, můžete ho upravit a spustit upravený kód tak , že znovu vyberete Spustit . Upravený kód se buď spustí v interaktivním okně, nebo pokud kompilace selže, zobrazí se v interaktivním okně všechny chybové zprávy kompilátoru jazyka C#.
Místní časové pásmoTry.NET inline code runner a playground je koordinovaný univerzální čas nebo UTC. To může ovlivnit chování a výstup příkladů, které ilustrují DateTime, DateTimeOffseta typy a TimeZoneInfo jejich členy.
Tento článek obsahuje několik příkladů, které používají DateTime
tento typ:
Příklady inicializace
- Vyvolání konstruktoru
- Vyvolání implicitního konstruktoru bez parametrů
- Přiřazení z návratové hodnoty
- Analýza řetězce, který představuje datum a čas
- Syntaxe jazyka Visual Basic pro inicializaci data a času
Formátování DateTime
objektů jako příkladů řetězců
- Použití výchozího formátu data a času
- Formátování data a času pomocí konkrétní jazykové verze
- Formátování data pomocí standardního nebo vlastního řetězce formátu
- Zadejte formátovací řetězec i konkrétní jazykovou verzi.
- Formátování data a času pomocí standardu ISO 8601 pro webové služby
Analýza řetězců jako DateTime
příkladů objektů
- Použití
Parse
neboTryParse
převod řetězce na datum a čas - Použití
ParseExact
neboTryParseExact
převod řetězce ve známém formátu - Převod z řetězcové reprezentace ISO 8601 na datum a čas
DateTime
Příklady řešení
Příklady kultury a kalendářů
- Zobrazení hodnot data a času pomocí kalendářů specifických pro jazykovou verzi
- Parsování řetězců podle kalendáře specifického pro jazykovou verzi
- Inicializace data a času z kalendáře konkrétní jazykové verze
- Přístup k vlastnostem data a času pomocí kalendáře konkrétní jazykové verze
- Načtení týdne v roce pomocí kalendářů specifických pro jazykovou verzi
Příklady trvalosti
- Zachování hodnot data a času jako řetězců v místním časovém pásmu
- Zachování hodnot data a času jako řetězců v jazykové verzi a čase ve neutrálním formátu
- Zachování hodnot data a času jako celých čísel
- Zachování hodnot data a času pomocí
XmlSerializer
Inicializace objektu DateTime
Počáteční hodnotu můžete k nové DateTime
hodnotě přiřadit mnoha různými způsoby:
- Volání konstruktoru, buď tam, kde zadáte argumenty pro hodnoty, nebo použijte implicitní konstruktor bez parametrů.
- Přiřazení
DateTime
k návratové hodnotě vlastnosti nebo metody - Analýza hodnoty z řetězcové
DateTime
reprezentace - Vytvoření instance instance
DateTime
jazyka pomocí jazykových funkcí specifických pro Jazyk jazyka Visual Basic
Následující fragmenty kódu ukazují příklady jednotlivých fragmentů kódu.
Vyvolání konstruktorů
Zavoláte jakékoli přetížení konstruktoru DateTime , který určuje prvky hodnoty data a času (například rok, měsíc a den nebo počet záškrtů). Následující kód vytvoří konkrétní datum pomocí konstruktoru DateTime určujícího rok, měsíc, den, hodinu, minutu a sekundu.
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}"
Implicitní konstruktor bez parametrů struktury vyvoláte DateTime
, když chcete DateTime
inicializovat výchozí hodnotu. (Podrobnosti o implicitní konstruktoru bez parametrů typu hodnoty najdete v tématu .Typy hodnot.) Některé kompilátory také podporují deklarování DateTime hodnoty bez explicitního přiřazení hodnoty. Výsledkem vytvoření hodnoty bez explicitní inicializace je také výchozí hodnota. Následující příklad znázorňuje DateTime implicitní konstruktor bez parametrů v jazyce C# a Visual Basic a také DateTime deklaraci bez přiřazení v jazyce 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}"
Přiřazení vypočítané hodnoty
Objektu můžete přiřadit DateTime hodnotu data a času vrácenou vlastností nebo metodou. Následující příklad přiřadí aktuální datum a čas, aktuální datum a čas koordinovaného univerzálního času (UTC) a aktuální datum třem novým DateTime proměnným.
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
Parsování řetězce, který představuje dateTime
Funkce Parse, ParseExacta TryParseTryParseExact metody všechny převádějí řetězec na ekvivalentní hodnotu data a času. Následující příklady používají metody ParseParseExact k analýze řetězce a jeho převodu DateTime na hodnotu. Druhý formát používá formát podporovaný standardem ISO 8601 pro reprezentaci data a času ve formátu řetězce. Tato standardní reprezentace se často používá k přenosu informací o datu ve webových službách.
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)
TryParseExact Metody TryParse označují, zda je řetězec platným vyjádřením DateTime hodnoty a pokud ano, provede převod.
Syntaxe specifická pro jazyk pro Visual Basic
Následující příkaz jazyka Visual Basic inicializuje novou DateTime hodnotu.
Dim date1 As Date = #5/1/2008 8:30:52AM#
Hodnoty DateTime a jejich řetězcové reprezentace
Interně jsou všechny DateTime hodnoty reprezentovány jako počet záškrtů (počet intervalů 100 nanosekund), které uplynuly od 12:00:00 půlnoci, 1. ledna 0001. Skutečná DateTime hodnota je nezávislá na způsobu, jakým se tato hodnota zobrazí při zobrazení. Vzhled DateTime hodnoty je výsledkem operace formátování, která převede hodnotu na řetězcové vyjádření.
Vzhled hodnot data a času závisí na jazykové verzi, mezinárodních standardech, požadavcích na aplikace a osobních preferencích. Struktura DateTime nabízí flexibilitu při formátování hodnot data a času prostřednictvím přetížení ToString. Výchozí DateTime.ToString() metoda vrátí řetězcovou reprezentaci hodnoty data a času pomocí krátkého vzorce data a času aktuální jazykové verze. Následující příklad používá výchozí DateTime.ToString() metodu. Zobrazí datum a čas pomocí krátkého formátu data a dlouhého času pro aktuální jazykovou verzi. Jazyková verze en-US je aktuální jazyková verze v počítači, na kterém byl příklad spuštěn.
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
Možná budete muset formátovat data v konkrétní jazykové verzi, aby podporovala webové scénáře, ve kterých může být server v jiné jazykové verzi než klient. Jazykovou verzi zadáte pomocí DateTime.ToString(IFormatProvider) metody k vytvoření krátkého data a dlouhého časového vyjádření v konkrétní jazykové verzi. Následující příklad používá metodu DateTime.ToString(IFormatProvider) k zobrazení data a času pomocí krátkého formátu data a dlouhého času pro jazykovou verzi fr-FR.
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
Jiné aplikace mohou vyžadovat odlišné řetězcové vyjádření data. Metoda DateTime.ToString(String) vrátí řetězcovou reprezentaci definovanou standardním nebo vlastním specifikátorem formátu pomocí konvencí formátování aktuální jazykové verze. Následující příklad používá metodu DateTime.ToString(String) k zobrazení vzoru úplného data a času pro jazykovou verzi en-US, aktuální jazykovou verzi v počítači, na kterém byl příklad spuštěn.
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
Nakonec můžete pomocí metody zadat jazykovou verzi i formát DateTime.ToString(String, IFormatProvider) . Následující příklad používá metodu DateTime.ToString(String, IFormatProvider) k zobrazení úplného formátu data a času pro jazykovou verzi fr-FR.
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
Přetížení DateTime.ToString(String) lze také použít s vlastním formátovacím řetězcem k určení jiných formátů. Následující příklad ukazuje, jak formátovat řetězec pomocí standardního formátu ISO 8601 , který se často používá pro webové služby. Formát ISO 8601 nemá odpovídající standardní formátovací řetězec.
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
Další informace o formátování DateTime hodnot naleznete v tématu Standardní řetězce formátu data a času a vlastní řetězce formátu data a času.
Analýza hodnot DateTime z řetězců
Analýza převede řetězcovou reprezentaci data a času na DateTime hodnotu. Řetězce data a času mají obvykle v aplikacích dva různé způsoby použití:
Datum a čas mají různé formy a odrážejí konvence aktuální jazykové verze nebo konkrétní jazykové verze. Aplikace například umožňuje uživateli, jehož aktuální jazyková verze je en-US, zadat hodnotu data jako "12/15/2013" nebo "15. prosince 2013". Umožňuje uživateli, jehož aktuální jazyková verze je en-gb, zadat hodnotu data jako 15. 12. 2013 nebo 15. prosince 2013.
Datum a čas jsou reprezentovány v předdefinovaném formátu. Například aplikace serializuje datum jako "20130103" nezávisle na jazykové verzi, na které je aplikace spuštěná. Aplikace může vyžadovat vstup kalendářních dat ve formátu krátkého data aktuální jazykové verze.
K převodu Parse řetězce z jednoho z běžných formátů data a času používaných jazykovou verzí na hodnotu použijete metodu nebo TryParse metodu DateTime . Následující příklad ukazuje, jak můžete použít TryParse k převodu řetězců kalendářních dat v různých formátech specifických pro jazykovou DateTime verzi na hodnotu. Změní aktuální jazykovou verzi na angličtinu (Spojené království) a zavolá metodu GetDateTimeFormats() pro vygenerování pole řetězců data a času. Pak předá každý prvek pole metodě TryParse . Výstup z příkladu ukazuje, že metoda analýzy mohla úspěšně převést všechny řetězce data a času specifické pro jazykovou verzi.
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
Pomocí ParseExact a TryParseExact metod převedete řetězec, který musí odpovídat určitému formátu nebo formátům DateTime na hodnotu. Jako parametr metody analýzy zadáte jeden nebo více řetězců formátu data a času. Následující příklad používá metodu TryParseExact(String, String[], IFormatProvider, DateTimeStyles, DateTime) k převodu řetězců, které musí být buď ve formátu "yyyYMMdd", nebo "HHmmss" na DateTime hodnoty.
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
Jedním z běžných použití ParseExact je převod řetězcové reprezentace z webové služby, obvykle ve standardním formátu ISO 8601 . Následující kód ukazuje správný formátovací řetězec, který se má použít:
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}")
Pokud řetězec nelze analyzovat, Parse metody a ParseExact vyvolá výjimku. Tyto TryParse metody TryParseExact vrátí Boolean hodnotu, která označuje, zda byl převod úspěšný nebo neúspěšný. Ve scénářích, ve kterých je důležitý výkon, byste měli použít TryParseTryParseExact metody. Operace analýzy řetězců data a času má tendenci mít vysokou míru selhání a zpracování výjimek je nákladné. Tyto metody použijte, pokud uživatelé zadávají řetězce nebo pocházejí z neznámého zdroje.
Další informace o analýze hodnot data a času najdete v tématu Analýza řetězců data a času.
Hodnoty data a času
Popisy časových hodnot v DateTime typu se často vyjadřují pomocí standardu UTC (Coordinated Universal Time). Koordinovaný univerzální čas je mezinárodně uznávaný název Greenwich Mean Time (GMT). Koordinovaný univerzální čas je čas měřený v nulové zeměpisné délce, počáteční bod UTC. Letní čas se nevztahuje na UTC.
Místní čas je relativní vzhledem k určitému časovému pásmu. Časové pásmo je přidruženo k posunu časového pásma. Posun časového pásma je posun časového pásma měřeného v hodinách od počátečního bodu UTC. Místní čas je navíc volitelně ovlivněn letním časem, který sčítá nebo odečte úpravu časového intervalu. Místní čas se vypočítá přidáním posunu časového pásma do utc a úpravou letního času v případě potřeby. Posun časového pásma v počátečním bodě UTC je nula.
Čas UTC je vhodný pro výpočty, porovnání a ukládání kalendářních dat a času v souborech. Místní čas je vhodný pro zobrazení v uživatelských rozhraních desktopových aplikací. Aplikace pracující s časovým pásmem (například mnoho webových aplikací) také potřebují pracovat s řadou dalších časových pásem.
Kind Pokud je DateTimeKind.Unspecifiedvlastnost objektu DateTime , není určena, zda je čas reprezentovaný místním časem, časem UTC nebo časem v jiném časovém pásmu.
Rozlišení data a času
Poznámka:
Jako alternativu k provádění aritmetických aritmetických DateTime hodnot k měření uplynulého času můžete použít Stopwatch třídu.
Vlastnost Ticks vyjadřuje hodnoty data a času v jednotkách 10000 sekundy. Vlastnost Millisecond vrátí tisíciny sekundy v hodnotě data a času. Použití opakovaných volání vlastnosti k DateTime.Now měření uplynulého času závisí na systémových hodinách. Systémové hodiny v systémech Windows 7 a Windows 8 mají rozlišení přibližně 15 milisekund. Toto rozlišení má vliv na malé časové intervaly kratší než 100 milisekund.
Následující příklad znázorňuje závislost aktuálních hodnot data a času na rozlišení systémových hodin. V příkladu se vnější smyčka opakuje 20krát a vnitřní smyčka slouží ke zpoždění vnější smyčky. Pokud je hodnota čítače vnější smyčky 10, volání Thread.Sleep metody zavádí zpoždění v pěti milisekundách. Následující příklad ukazuje počet milisekund vrácených DateTime.Now.Milliseconds
vlastností změny až po volání 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
Operace data a času
Výpočet pomocí DateTime struktury, například Add nebo Subtract, nemění hodnotu struktury. Místo toho výpočet vrátí novou DateTime strukturu, jejíž hodnota je výsledkem výpočtu.
Operace převodu mezi časovými pásmy (například mezi UTC a místním časem nebo mezi jedním časovým pásmem a jiným) berou v úvahu letní čas, ale aritmetické a srovnávací operace ne.
Samotná DateTime struktura nabízí omezenou podporu pro převod z jednoho časového pásma na jiné. Metodu můžete použít k převodu ToLocalTime UTC na místní čas nebo můžete použít metodu k převodu ToUniversalTime z místního času na UTC. Úplná sada metod převodu časových pásem je však k dispozici ve TimeZoneInfo třídě. Pomocí těchto metod převedete čas v libovolném časovém pásmu na čas v libovolném časovém pásmu.
Výpočty a porovnání DateTime objektů jsou smysluplné pouze v případě, že objekty představují časy ve stejném časovém pásmu. Objekt můžete použít TimeZoneInfo k reprezentaci DateTime časového pásma hodnoty, i když jsou tyto dva volně svázané. Objekt DateTime nemá vlastnost, která vrací objekt, který představuje časové pásmo hodnoty data a času. Vlastnost Kind označuje, zda DateTime
představuje UTC, místní čas nebo není zadán. V aplikaci pracující s časovým pásmem je nutné spoléhat na určitý externí mechanismus k určení časového pásma, ve kterém DateTime byl objekt vytvořen. Můžete použít strukturu, která zabalí hodnotu i DateTimeTimeZoneInfo objekt, který představuje DateTime časové pásmo hodnoty. Podrobnosti o používání standardu UTC ve výpočtech a porovnání s DateTime hodnotami najdete v tématu Provádění Aritmetických operací s kalendářními daty a časy.
Každý DateTime člen implicitně používá gregoriánský kalendář k provedení své operace. Výjimky jsou metody, které implicitně určují kalendář. Patří sem konstruktory, které určují kalendář a metody s parametrem odvozeným z IFormatProvider, například System.Globalization.DateTimeFormatInfo.
Operace podle členů DateTime typu berou v úvahu podrobnosti, jako jsou přestupné roky a počet dní v měsíci.
Hodnoty dateTime a kalendáře
Knihovna tříd .NET obsahuje řadu tříd kalendáře, z nichž všechny jsou odvozené od Calendar třídy. Mezi ně patří:
- Třída ChineseLunisolarCalendar .
- Třída EastAsianLunisolarCalendar .
- Třída GregorianCalendar .
- Třída HebrewCalendar .
- Třída HijriCalendar .
- Třída JapaneseCalendar .
- Třída JapaneseLunisolarCalendar .
- Třída JulianCalendar .
- Třída KoreanCalendar .
- Třída KoreanLunisolarCalendar .
- Třída PersianCalendar .
- Třída TaiwanCalendar .
- Třída TaiwanLunisolarCalendar .
- Třída ThaiBuddhistCalendar .
- Třída UmAlQuraCalendar .
Důležité
Éry v japonských kalendářích jsou založeny na vládě císaře, a proto se očekává, že se změní. Například 1. května 2019 označil začátek období Reiwa v roce 2019 a JapaneseCalendarJapaneseLunisolarCalendar. Taková změna éry ovlivňuje všechny aplikace, které tyto kalendáře používají. Další informace a určení, zda jsou ovlivněny vaše aplikace, naleznete v tématu Zpracování nové éry v japonském kalendáři v .NET. Informace o testování aplikací v systémech Windows za účelem zajištění připravenosti na změnu v éře najdete v tématu Příprava aplikace na změnu japonské éry. Funkce v .NET, které podporují kalendáře s více obdobími a osvědčené postupy při práci s kalendáři, které podporují více období, najdete v tématu Práce s obdobími.
Každá jazyková verze používá výchozí kalendář definovaný vlastností jen pro CultureInfo.Calendar čtení. Každá jazyková verze může podporovat jeden nebo více kalendářů definovaných vlastností jen pro CultureInfo.OptionalCalendars čtení. Kalendář aktuálně používaný konkrétním CultureInfo objektem je definován jeho DateTimeFormatInfo.Calendar vlastností. Musí to být jeden z kalendářů nalezených CultureInfo.OptionalCalendars v poli.
Aktuální kalendář jazykové verze se používá ve všech operacích formátování této jazykové verze. Například výchozí kalendář thajské buddhistické kultury je thajský buddhistický kalendář, který je reprezentován ThaiBuddhistCalendar třídou. Pokud se CultureInfo v operaci formátování data a času používá objekt představující thajskou buddhistickou kulturu, je ve výchozím nastavení používán kalendář thajské buddhistické éry. Gregoriánský kalendář se používá pouze v případě, že se změní vlastnost jazykové verze DateTimeFormatInfo.Calendar , jak ukazuje následující příklad:
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
Aktuální kalendář jazykové verze se také používá ve všech operacích analýzy této jazykové verze, jak ukazuje následující příklad.
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
DateTime Vytvoříte instanci hodnoty pomocí prvků data a času (počet roku, měsíce a dne) konkrétního kalendáře zavoláním konstruktoruDateTime, který obsahuje calendar
parametr a předá ho Calendar objektu, který tento kalendář představuje. Následující příklad používá prvky data a času z ThaiBuddhistCalendar kalendáře.
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 konstruktory, které neobsahují calendar
parametr, předpokládají, že prvky data a času jsou vyjádřeny jako jednotky v gregoriánském kalendáři.
Všechny ostatní DateTime vlastnosti a metody používají gregoriánský kalendář. Například DateTime.Year vlastnost vrátí rok v gregoriánském kalendáři a DateTime.IsLeapYear(Int32) metoda předpokládá, že year
parametr je rok v gregoriánském kalendáři. Každý DateTime člen, který používá gregoriánský kalendář má odpovídající člen Calendar třídy, který používá určitý kalendář. Metoda například Calendar.GetYear vrátí rok v určitém kalendáři a Calendar.IsLeapYear metoda interpretuje year
parametr jako číslo roku v konkrétním kalendáři. Následující příklad používá jak odpovídající členy třídy, tak DateTime i odpovídající členy ThaiBuddhistCalendar třídy.
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
Struktura DateTime obsahuje DayOfWeek vlastnost, která vrátí den v týdnu v gregoriánském kalendáři. Nezahrnuje člena, který umožňuje načíst číslo týdne v roce. Pokud chcete načíst týden v roce, zavolejte metodu individuálního Calendar.GetWeekOfYear kalendáře. V následujícím příkladu je uvedena ukázka.
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
Další informace o kalendářních datech a kalendářích najdete v tématu Práce s kalendáři.
Zachování hodnot DateTime
Hodnoty můžete zachovat DateTime následujícími způsoby:
- Převeďte je na řetězce a zachovají řetězce.
- Převeďte je na 64bitové celočíselné hodnoty (hodnota Ticks vlastnosti) a zachovají celá čísla.
- Serializace hodnot DateTime.
Je nutné zajistit, aby rutina, která obnoví DateTime hodnoty, nepřišla o data nebo vyvolala výjimku bez ohledu na to, kterou techniku zvolíte. DateTime hodnoty by měly být zaokrouhlené. To znamená, že původní hodnota a obnovená hodnota by měly být stejné. A pokud původní DateTime hodnota představuje jeden okamžik času, měl by identifikovat stejný okamžik času, kdy se obnoví.
Zachování hodnot jako řetězců
Chcete-li úspěšně obnovit DateTime hodnoty, které jsou trvalé jako řetězce, postupujte podle těchto pravidel:
Při obnovování řetězce proveďte stejné předpoklady týkající se formátování specifické pro jazykovou verzi, jako když jste ho zachovali. Chcete-li zajistit, aby byl řetězec obnoven v systému, jehož aktuální jazyková verze se liší od jazykové verze systému, ve které byl uložen, zavolejte ToString přetížení pro uložení řetězce pomocí konvencí invariantní jazykové verze. Parse(String, IFormatProvider, DateTimeStyles) Voláním nebo TryParse(String, IFormatProvider, DateTimeStyles, DateTime) přetížením obnovte řetězec pomocí konvencí invariantní jazykové verze. Nikdy nepoužívejte ToString(), Parse(String)nebo TryParse(String, DateTime) přetížení, které používají konvence aktuální jazykové verze.
Pokud datum představuje jeden okamžik času, ujistěte se, že představuje stejný okamžik v čase, kdy se obnoví, a to i v jiném časovém pásmu. Před uložením DateTime nebo použitím DateTimeOffsetpřeveďte hodnotu na koordinovaný univerzální čas (UTC).
Nejběžnější chybou při zachování DateTime hodnot jako řetězců je spoléhat se na konvence formátování výchozí nebo aktuální jazykové verze. K problémům dochází v případě, že se aktuální jazyková verze při ukládání a obnovování řetězců liší. Následující příklad ukazuje tyto problémy. Ukládá pět kalendářních dat pomocí konvencí formátování aktuální jazykové verze, což je v tomto případě angličtina (USA). Obnoví data pomocí konvencí formátování jiné jazykové verze, což je v tomto případě angličtina (Spojené království). Vzhledem k tomu, že konvence formátování těchto dvou jazykových verzí se liší, nelze obnovit dvě data a zbývající tři kalendářní data jsou interpretována nesprávně. Pokud původní hodnoty data a času představují jednotlivé momenty v čase, jsou obnovené časy nesprávné, protože informace o časovém pásmu jsou ztraceny.
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...
Pokud chcete hodnoty odezvy úspěšně dokončit DateTime , postupujte takto:
- Pokud hodnoty představují jeden okamžik času, převeďte je z místního času na UTC voláním ToUniversalTime metody.
- Převeďte kalendářní data na jejich řetězcové reprezentace voláním ToString(String, IFormatProvider) nebo String.Format(IFormatProvider, String, Object[]) přetížením. Pomocí konvencí formátování invariantní jazykové verze zadejte CultureInfo.InvariantCulture jako
provider
argument. Zadejte, že hodnota by měla být zaokrouhlená pomocí standardního řetězce formátu "O" nebo "R".
Pokud chcete obnovit trvalé DateTime hodnoty bez ztráty dat, postupujte takto:
- Parsujte data voláním ParseExact nebo TryParseExact přetížením. Zadejte CultureInfo.InvariantCulture jako
provider
argument a použijte stejný standardní formátovací řetězec, který jste použili pro argument během převoduformat
. Zahrňte DateTimeStyles.RoundtripKind hodnotu do argumentustyles
. - DateTime Pokud hodnoty představují jednotlivé momenty v čase, zavolejte metoduToLocalTime, která převede parsované datum z UTC na místní čas.
Následující příklad používá invariantní jazykovou verzi a řetězec standardního formátu "O" k zajištění, že DateTime hodnoty uložené a obnovené představují stejný okamžik v čase bez ohledu na systém, jazykovou verzi nebo časové pásmo zdrojového a cílového systému.
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...
Zachování hodnot jako celých čísel
Datum a čas můžete zachovat jako Int64 hodnotu, která představuje počet záškrtů. V takovém případě nemusíte uvažovat o jazykové verzi systémů DateTime , u kterých jsou hodnoty trvalé a obnovené.
DateTime Zachování hodnoty jako celého čísla:
- DateTime Pokud hodnoty představují jeden okamžik v čase, převeďte je na UTC voláním ToUniversalTime metody.
- Načtěte počet záškrtů reprezentovaných DateTime hodnotou z jeho Ticks vlastnosti.
DateTime Obnovení hodnoty, která byla zachována jako celé číslo:
- Vytvořte instanci nového DateTime objektu předáním Int64 hodnoty konstruktoru DateTime(Int64) .
- DateTime Pokud hodnota představuje jeden okamžik v čase, převeďte ji z UTC na místní čas voláním ToLocalTime metody.
Následující příklad zachovává pole DateTime hodnot jako celá čísla v systému v americkém časovém pásmu Tichomoří. Obnoví ho v systému v zóně UTC. Soubor obsahující celá čísla obsahuje Int32 hodnotu, která označuje celkový počet Int64 hodnot, které se za ním okamžitě následují.
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...
Serializace hodnot DateTime
Hodnoty můžete zachovat DateTime prostřednictvím serializace do datového proudu nebo souboru a pak je obnovit prostřednictvím deserializace. DateTime data jsou serializována v určitém zadaném formátu objektu. Objekty jsou obnoveny při deserializaci. Formátovač nebo serializátor, například JsonSerializer nebo XmlSerializer, zpracovává proces serializace a deserializace. Další informace o serializaci a typech serializace podporované rozhraním .NET naleznete v tématu Serializace.
Následující příklad používá XmlSerializer třídu serializovat a deserializovat DateTime hodnoty. Hodnoty představují všechny přestupné dny v dvaceti prvním století. Výstup představuje výsledek, pokud je příklad spuštěn v systému, jehož aktuální jazyková verze je angličtina (Spojené království). Vzhledem k tomu, že jste deserializovali DateTime samotný objekt, kód nemusí zpracovávat kulturní rozdíly ve formátech data a času.
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
Předchozí příklad neobsahuje informace o čase. DateTime Pokud hodnota představuje okamžik v čase a je vyjádřena jako místní čas, převeďte ji z místního času na UTC před serializací voláním ToUniversalTime metody. Po deserializaci ji převeďte z UTC na místní čas voláním ToLocalTime metody.
Datum a čas vs. časový interval
Typy DateTime hodnot se TimeSpan liší v tom, že DateTime představuje okamžik v čase, zatímco TimeSpan představuje časový interval. Pokud chcete získat TimeSpan objekt, který představuje časový interval mezi nimi, můžete odečíst jednu instanci DateTime z jiného objektu. Nebo můžete k aktuálnímu datu DateTimeDateTime přidat pozitivní TimeSpan hodnotu, která představuje budoucí datum.
Časový interval můžete od objektu DateTime přičíst nebo odečíst. Časové intervaly můžou být záporné nebo kladné a dají se vyjádřit v jednotkách, jako jsou ticks, sekundy nebo jako TimeSpan objekt.
Porovnání rovnosti v rámci tolerance
Porovnání rovnosti pro DateTime hodnoty jsou přesné. Aby bylo možné považovat za stejné, musí být dvě hodnoty vyjádřeny jako stejný počet záškrtů. Tato přesnost je často zbytečná nebo dokonce nesprávná pro mnoho aplikací. Často chcete testovat, jestli DateTime jsou objekty přibližně stejné.
Následující příklad ukazuje, jak porovnat zhruba ekvivalentní DateTime hodnoty. Při deklarování rovných hodnot přijímá malý rozdíl.
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
Hlediska zprostředkovatele komunikace s objekty
Hodnota DateTime , která se přenese do aplikace MODELU COM, pak se přenese zpět do spravované aplikace, se říká na zpáteční cestu. Hodnota DateTime , která určuje pouze čas, ale nenačte odezvu, jak byste mohli očekávat.
Je-li zpáteční cesta pouze čas, například 3:000, konečné datum a čas je 30. prosince 1899 C.E. v 3:00 v 1. lednu místo 1. ledna 0001 C.E. v 3:00. Net a COM předpokládají výchozí datum, pokud je zadán pouze čas. Systém COM však předpokládá základní datum 30. prosince 1899 C.E., zatímco .NET předpokládá základní datum 1. ledna 0001 C.E.
Pokud se z .NET do modelu COM předá pouze čas, provede se speciální zpracování, které převede čas na formát používaný objektem COM. Pokud se z modelu COM do .NET předá pouze čas, neprovádí se žádné zvláštní zpracování, protože by to poškodilo legitimní data a časy dne 30. prosince 1899 nebo před ní. Pokud datum zahájí zpáteční cestu z modelu COM, zachová .NET a COM datum.
Chování rozhraní .NET a MODELU COM znamená, že pokud vaše aplikace zaokrouhlí DateTime pouze čas, musí aplikace pamatovat na změnu nebo ignorování chybného data z konečného DateTime objektu.