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.

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

Formátování DateTime objektů jako příkladů řetězců

Analýza řetězců jako DateTime příkladů objektů

DateTime Příklady řešení

Příklady kultury a kalendářů

Příklady trvalosti

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 DateTimejazyka 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ří:

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:

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:

  1. Pokud hodnoty představují jeden okamžik času, převeďte je z místního času na UTC voláním ToUniversalTime metody.
  2. 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:

  1. 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řevodu format . Zahrňte DateTimeStyles.RoundtripKind hodnotu do argumentu styles .
  2. 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:

  1. DateTime Pokud hodnoty představují jeden okamžik v čase, převeďte je na UTC voláním ToUniversalTime metody.
  2. 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:

  1. Vytvořte instanci nového DateTime objektu předáním Int64 hodnoty konstruktoru DateTime(Int64) .
  2. 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.