Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Ten artykuł zawiera dodatkowe uwagi dotyczące dokumentacji referencyjnej dla tego interfejsu API.
Ważne
Era w japońskich kalendarzach opiera się na panowaniu cesarza i dlatego oczekuje się, że się zmieni. Na przykład 1 maja 2019 r. oznaczało początek ery Reiwa w JapaneseCalendar i JapaneseLunisolarCalendar. Taka zmiana ery wpływa na wszystkie aplikacje korzystające z tych kalendarzy. Aby uzyskać więcej informacji i określić, czy twoje aplikacje mają wpływ, zobacz Obsługa nowej ery w kalendarzu japońskim na platformie .NET. Aby uzyskać informacje na temat testowania aplikacji w systemach Windows w celu zapewnienia gotowości do zmiany ery, zobacz Przygotowanie aplikacji do zmiany w erze japońskiej. Aby uzyskać informacje o funkcjach na platformie .NET, które obsługują kalendarze z wieloma epokami i aby uzyskać najlepsze rozwiązania dotyczące pracy z kalendarzami obsługującymi wiele epok, zobacz Praca z erami.
Przegląd
Typ DateTime wartości reprezentuje daty i godziny z wartościami od 00:00:00 (północ), 1 stycznia 0001 roku naszej ery (n.e.) do 23:59:59, 31 grudnia 9999 roku n.e. w kalendarzu gregoriańskim.
Wartości czasu są mierzone w 100-nanosekundowych jednostkach nazywanych tikami. Konkretna data to liczba kleszczy od 12:00 północy, 1 stycznia 0001 R. (C.E.) w kalendarzu GregorianCalendar . Liczba nie obejmuje tików, które zostałyby dodane przez sekundy przestępne. Na przykład wartość znaczników 31241376000000000L reprezentuje datę piątek, 01 stycznia 0100 12:00:00 północy. DateTime Wartość jest zawsze wyrażana w kontekście jawnego lub domyślnego kalendarza.
Uwaga
Jeśli pracujesz z wartością znaczników, którą chcesz przekonwertować na inny interwał czasu, taki jak minuty lub sekundy, należy użyć zmiennej TimeSpan.TicksPerDay, TimeSpan.TicksPerHour, TimeSpan.TicksPerMinute, TimeSpan.TicksPerSecondlub TimeSpan.TicksPerMillisecond stałej, aby wykonać konwersję. Aby na przykład dodać liczbę sekund reprezentowanych przez określoną liczbę taktów do składnika Second wartości DateTime, możesz użyć wyrażenia dateValue.Second + nTicks/Timespan.TicksPerSecond
.
Źródło całego zestawu przykładów można wyświetlić w tym artykule w języku Visual Basic, F# lub C#.
Uwaga
Alternatywą dla struktury DateTime, używanej do pracy z wartościami daty i czasu w określonych strefach czasowych, jest struktura DateTimeOffset. Struktura DateTimeOffset przechowuje informacje o dacie i godzinie w polu prywatnym DateTime oraz liczbę minut, w których data i godzina różnią się od czasu UTC w polu prywatnym Int16 . Dzięki temu wartość DateTimeOffset może odzwierciedlać czas w określonej strefie czasowej, natomiast DateTime wartość może jednoznacznie odzwierciedlać tylko czas UTC i czas lokalnej strefy czasowej. Aby dowiedzieć się, kiedy używać struktury DateTime lub struktury DateTimeOffset podczas pracy z wartościami daty i godziny, zobacz Wybieranie między DateTime, DateTimeOffset, TimeSpan i TimeZoneInfo.
Szybkie linki do przykładowego kodu
Uwaga
Niektóre przykłady języka C# w tym artykule są uruchamiane w Try.NET wbudowanym module uruchamiania kodu i środowisku. Wybierz przycisk Uruchom, aby uruchomić przykład w oknie interaktywnym. Po wykonaniu kodu można go zmodyfikować i uruchomić zmodyfikowany kod, wybierając ponownie Uruchom. Zmodyfikowany kod jest uruchamiany w oknie interaktywnym lub, jeśli kompilacja zakończy się niepowodzeniem, w oknie interaktywnym zostaną wyświetlone wszystkie komunikaty o błędach kompilatora języka C#.
Lokalna strefa czasowa wbudowanego uruchamiającego kod Try.NET i placu zabaw to uniwersalny czas koordynowany, czyli UTC. Może to mieć wpływ na zachowanie i dane wyjściowe przykładów ilustrujących DateTime, DateTimeOffset, i TimeZoneInfo typy oraz ich członków.
Ten artykuł zawiera kilka przykładów, które używają DateTime
typu:
Przykłady inicjowania
- Wywoływanie konstruktora
- Wywoływanie niejawnego konstruktora bez parametrów
- Przypisanie z wartości zwracanej
- Analizowanie ciągu reprezentującego datę i godzinę
- Składnia języka Visual Basic do inicjowania daty i godziny
Formatowanie obiektów DateTime
jako ciągi - przykłady
- Użyj domyślnego formatu daty i godziny
- Formatowanie daty i godziny przy użyciu określonej kultury
- Formatowanie daty i czasu przy użyciu standardowego lub niestandardowego ciągu formatu
- Określanie zarówno ciągu formatu, jak i określonej kultury
- Formatowanie daty i godziny przy użyciu standardu ISO 8601 dla usług internetowych
Parsowanie ciągów jako przykłady obiektów DateTime
-
Użyj
Parse
lubTryParse
do konwersji ciągu na datę i godzinę -
Użyj
ParseExact
lubTryParseExact
do konwersji ciągu w znanym formacie - Konwertowanie z reprezentacji ciągu ISO 8601 na datę i godzinę
DateTime
przykłady rozwiązywania problemów
- Eksplorowanie rozdzielczości wartości daty i godziny
- Porównywanie równości z uwzględnieniem tolerancji
Przykłady kultur i kalendarzy
- Wyświetlanie wartości daty i godziny przy użyciu kalendarzy specyficznych dla kultury
- Analizowanie ciągów zgodnie z kalendarzem specyficznym dla kultury
- Inicjalizowanie daty i godziny na podstawie kalendarza danej kultury
- Uzyskiwanie dostępu do właściwości daty i godziny przy użyciu kalendarza określonej kultury
- Pobieranie tygodnia roku przy użyciu kalendarzy specyficznych dla kultury
Przykłady trwałości
- Utrwalanie wartości daty i godziny jako ciągów w lokalnej strefie czasowej
- Utrwalanie wartości daty i godziny jako ciągów w formacie niezależnym od kultury i czasu
- Utrwalanie wartości daty i godziny jako liczby całkowite
-
Utrwalanie wartości daty i godziny przy użyciu elementu
XmlSerializer
Inicjowanie obiektu DateTime
Wartość początkową można przypisać do nowej DateTime
wartości na wiele różnych sposobów:
- Wywołanie konstruktora, w którym można określić argumenty dla wartości lub użyć niejawnego konstruktora bez parametrów.
- Przypisywanie elementu
DateTime
do wartości zwracanej właściwości lub metody. - Analizowanie
DateTime
wartości z jej reprezentacji w postaci ciągu znaków. - Używanie funkcji specyficznych dla języka Visual Basic w celu utworzenia wystąpienia elementu
DateTime
.
Poniższe fragmenty kodu pokazują przykłady każdego z nich.
Wywoływanie konstruktorów
Wywołujesz dowolne przeciążenia DateTime konstruktora, dzięki którym można określać elementy wartości daty i godziny (takie jak rok, miesiąc i dzień lub liczba tików). Poniższy kod tworzy określoną datę przy użyciu konstruktora określającego DateTime rok, miesiąc, dzień, godzinę, minutę i sekundę.
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}"
Wywołujesz niejawny konstruktor bez parametrów struktury DateTime
, gdy chcesz, aby DateTime
został zainicjowany do jego wartości domyślnej. (Aby uzyskać szczegółowe informacje na temat niejawnego konstruktora bez parametrów typu wartości, zobacz Typy wartości). Niektóre kompilatory obsługują również deklarowanie DateTime wartości bez jawnego przypisania do niej wartości. Utworzenie wartości bez jawnej inicjalizacji również skutkuje wartością domyślną. W poniższym przykładzie przedstawiono DateTime niejawny konstruktor bez parametrów w języku C# i Visual Basic, a także deklarację DateTime bez przypisania w języku 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}"
Przypisywanie obliczonej wartości
Można przypisać obiektowi DateTime wartość daty i godziny zwracaną przez właściwość lub metodę. Poniższy przykład przypisuje bieżącą datę i godzinę, bieżącą datę i godzinę uniwersalnej koordynowanej (UTC) oraz bieżącą datę do trzech nowych DateTime zmiennych.
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
Analizowanie ciągu reprezentującego wartość DateTime
Metody Parse, ParseExact, TryParsei TryParseExact konwertują ciąg na równoważną wartość daty i godziny. W poniższych przykładach używane są metody Parse i ParseExact, aby przeanalizować ciąg i przekonwertować go na wartość DateTime. Drugi format używa formy obsługiwanej przez standard ISO 8601 do reprezentowania daty i godziny w formacie ciągu. Ta standardowa reprezentacja jest często używana do transferu informacji o dacie w usługach internetowych.
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)
Metody TryParse i TryParseExact wskazują, czy ciąg jest prawidłową reprezentacją DateTime wartości, a jeśli tak, wykonuje konwersję.
Składnia specyficzna dla Visual Basic
Poniższa instrukcja języka Visual Basic inicjuje nową DateTime wartość.
Dim date1 As Date = #5/1/2008 8:30:52AM#
Wartości DateTime i ich reprezentacje jako ciągi znaków
Wewnętrznie wszystkie DateTime wartości są reprezentowane jako liczba tyknięć (liczba interwałów po 100 nanosekund), które upłynęły od północy o godzinie 00:00:00, 1 stycznia roku 0001. Rzeczywista DateTime wartość jest niezależna od sposobu, w jaki ta wartość jest przedstawiana. Wygląd DateTime wartości jest wynikiem operacji formatowania, która konwertuje wartość na jej reprezentację ciągu.
Wygląd wartości daty i godziny zależy od kultury, standardów międzynarodowych, wymagań aplikacji i preferencji osobistych. Struktura DateTime zapewnia elastyczność formatowania wartości daty i godziny poprzez przeciążenia ToString. Metoda domyślna DateTime.ToString() zwraca ciąg reprezentujący wartość daty i godziny, używając krótkiego wzorca daty i długiego wzorca czasu bieżącej kultury. W poniższym przykładzie użyto metody domyślnej DateTime.ToString() . Wyświetla datę i godzinę przy użyciu wzorca daty krótkiej i godziny długiej zgodnie z bieżącą kulturą. Kultura systemu en-US jest bieżącą kulturą na komputerze, na którym uruchomiono przykład.
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że być konieczne sformatowanie dat w określonej kulturze w celu obsługi scenariuszy internetowych, w których serwer może znajdować się w innej kulturze niż klient. Należy określić kulturę za pomocą metody DateTime.ToString(IFormatProvider), aby utworzyć skróconą datę oraz długie przedstawienie czasu w tej kulturze. W poniższym przykładzie użyto DateTime.ToString(IFormatProvider) metody do wyświetlenia daty i godziny przy użyciu wzorca daty krótkiej i długiej dla kultury 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
Inne aplikacje mogą wymagać różnych reprezentacji ciągów daty. Metoda DateTime.ToString(String) zwraca reprezentację ciągu zdefiniowaną przez specyfikator formatu standardowego lub niestandardowego przy użyciu konwencji formatowania bieżącej kultury. W poniższym przykładzie metoda DateTime.ToString(String) jest używana do wyświetlania wzorca pełnej daty i czasu dla kultury en-US, obecnej kultury na komputerze, na którym uruchomiono przykład.
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
Na koniec można określić zarówno kulturę, jak i format przy użyciu DateTime.ToString(String, IFormatProvider) metody . W poniższym przykładzie użyto metody DateTime.ToString(String, IFormatProvider), aby wyświetlić pełny wzorzec daty i czasu dla kultury 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
Przeciążenie DateTime.ToString(String) może być również używane z ciągiem formatu niestandardowego, aby określić inne formaty. W poniższym przykładzie pokazano, jak sformatować ciąg przy użyciu standardowego formatu ISO 8601 często używanego dla usług internetowych. Format Iso 8601 nie ma odpowiedniego standardowego ciągu formatu.
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
Aby uzyskać więcej informacji na temat formatowania DateTime wartości, zobacz Standardowe ciągi formatu daty i godziny oraz niestandardowe ciągi formatu daty i godziny.
Analizowanie wartości DateTime z ciągów
Analizowanie konwertuje ciąg reprezentujący datę i godzinę na DateTime wartość. Zazwyczaj ciągi daty i godziny mają dwa różne zastosowania w aplikacjach:
Data i godzina mają różne formy i odzwierciedlają konwencje bieżącej kultury lub konkretnej kultury. Na przykład aplikacja umożliwia użytkownikowi, którego bieżąca kultura jest en-US wprowadzić wartość daty jako "12/15/2013" lub "15 grudnia 2013". Umożliwia to użytkownikowi, którego bieżąca kultura jest en-gb, aby wprowadzić wartość daty jako "15/12/2013" lub "15 grudnia 2013 r.".
Data i godzina są reprezentowane w wstępnie zdefiniowanym formacie. Na przykład aplikacja serializuje datę jako "20130103" niezależnie od kultury, na której działa aplikacja. Aplikacja może wymagać wprowadzania dat w formacie krótkiej daty zgodnym z bieżącą kulturą.
Metoda Parse lub TryParse służy do konwertowania ciągu z jednego z typowych formatów daty i godziny używanych przez kulturę na wartość DateTime. Poniższy przykład przedstawia sposób zamiany ciągów dat TryParse w różnych formatach charakterystycznych dla różnych kultur na wartość DateTime. Zmienia bieżącą kulturę ustawień na angielski (Wielka Brytania) i wywołuje metodę GetDateTimeFormats() aby wygenerować tablicę ciągów daty i godziny. Następnie przekazuje każdy element w tablicy do metody TryParse. Dane wyjściowe z przykładu pokazują, że metoda analizowania mogła pomyślnie przekonwertować każdy ciąg daty i godziny specyficzny dla kultury.
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
Używasz metody ParseExact i TryParseExact do konwertowania ciągu, który musi być zgodny z określonym formatem lub formatami na wartość DateTime. Należy określić co najmniej jeden ciąg formatu daty i godziny jako parametr metody analizowania. W poniższym przykładzie użyto metody TryParseExact(String, String[], IFormatProvider, DateTimeStyles, DateTime), aby przekonwertować ciągi, które muszą mieć format "rrrrMMdd" lub "HHmmss", na wartości DateTime.
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
Jednym z typowych zastosowań ParseExact jest konwersja reprezentacji ciągu znaków z usługi internetowej, zazwyczaj w formacie standardowym ISO 8601. Poniższy kod przedstawia prawidłowy ciąg formatu do użycia:
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}")
Jeśli nie można przeanalizować ciągu, Parse metody i ParseExact zgłaszają wyjątek. Metody TryParse i TryParseExact zwracają wartość wskazującą Boolean , czy konwersja powiodła się, czy nie powiodła się. Powinieneś używać metod TryParse lub TryParseExact w scenariuszach, w których wydajność jest ważna. Operacja parsowania ciągów daty i godziny ma tendencję do wysokiego wskaźnika niepowodzenia, a obsługa wyjątków jest kosztowna. Użyj tych metod, jeśli ciągi są wprowadzane przez użytkowników lub pochodzące z nieznanego źródła.
Aby uzyskać więcej informacji na temat analizowania wartości daty i godziny, zobacz Analizowanie ciągów daty i godziny.
Wartości typu DateTime
Opisy wartości czasu w typie DateTime są często wyrażane przy użyciu standardu uniwersalnego czasu koordynowanego (UTC). Uniwersalny czas koordynowany jest międzynarodowo rozpoznaną nazwą Greenwich Mean Time (GMT). Uniwersalny czas koordynowany to czas mierzony o długości geograficznej zero stopni, punkt początkowy UTC. Czas letni nie ma zastosowania do czasu UTC.
Czas lokalny jest względny dla określonej strefy czasowej. Strefa czasowa jest skojarzona z przesunięciem strefy czasowej. Przesunięcie strefy czasowej to przesunięcie strefy czasowej mierzone w godzinach od punktu początkowego UTC. Ponadto czas lokalny jest opcjonalnie objęty zmianą czasu letniego, co powoduje dodanie lub odejmowanie korekty interwału czasu. Czas lokalny jest obliczany przez dodanie przesunięcia strefy czasowej do czasu UTC i uwzględnienie czasu letniego w razie potrzeby. Przesunięcie strefy czasowej w punkcie początkowym UTC wynosi zero.
Czas UTC nadaje się do obliczeń, porównań i przechowywania dat i godzin w plikach. Czas lokalny jest odpowiedni do wyświetlania w interfejsach użytkownika aplikacji pulpitowych. Aplikacje obsługujące strefę czasową (takie jak wiele aplikacji internetowych) muszą również współpracować z wieloma innymi strefami czasowymi.
Kind Jeśli właściwość DateTime obiektu to DateTimeKind.Unspecified, nie jest określona, czy czas reprezentowany to czas lokalny, czas UTC, czy czas w innej strefie czasowej.
Precyzja daty i godziny
Uwaga
Alternatywą dla przeprowadzania operacji na wartościach DateTime w celu mierzenia upływu czasu może być zastosowanie klasy Stopwatch.
Właściwość Ticks wyraża wartości daty i godziny w jednostkach jednej dziesiątej części sekundy. Właściwość Millisecond zwraca tysięczne części sekundy w wartości daty i czasu. Używanie powtarzających się wywołań do DateTime.Now właściwości w celu pomiaru czasu, który upłynął, zależy od zegara systemowego. Zegar systemowy w systemach Windows 7 i Windows 8 ma rozdzielczość około 15 milisekund. Ta rozdzielczość ma wpływ na małe interwały czasowe mniejsze niż 100 milisekund.
Poniższy przykład ilustruje zależność bieżących wartości daty i godziny od rozdzielczości zegara systemowego. W tym przykładzie pętla zewnętrzna powtarza się 20 razy, a pętla wewnętrzna służy do opóźnienia pętli zewnętrznej. Jeśli wartość licznika pętli zewnętrznej wynosi 10, wywołanie Thread.Sleep metody wprowadza pięć milisekund opóźnienia. W poniższym przykładzie pokazano, że liczba milisekund zwrócona przez właściwość DateTime.Now.Milliseconds
zmienia się dopiero po wywołaniu 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
Operacje datetime
Obliczenie przy użyciu DateTime struktury, takiej jak Add lub Subtract, nie modyfikuje wartości struktury. Zamiast tego obliczenie zwraca nową DateTime strukturę, której wartość jest wynikiem obliczenia.
Operacje konwersji między strefami czasowymi (na przykład między czasem UTC a czasem lokalnym lub między jedną strefą czasową a drugą) uwzględniają czas letni, ale operacje arytmetyczne i porównawcze nie.
Sama DateTime struktura oferuje ograniczoną obsługę konwersji z jednej strefy czasowej na inną. Możesz użyć ToLocalTime metody , aby przekonwertować czas UTC na lokalny lub użyć ToUniversalTime metody do konwersji z czasu lokalnego na UTC. Jednak w klasie jest dostępny pełny zestaw metod konwersji strefy czasowej TimeZoneInfo . Czas można przekonwertować w dowolnej ze stref czasowych na czas w dowolnej innej strefie czasowej przy użyciu tych metod.
Obliczenia i porównania DateTime obiektów mają znaczenie tylko wtedy, gdy obiekty reprezentują czas w tej samej strefie czasowej. Można użyć TimeZoneInfo obiektu do reprezentowania DateTime strefy czasowej wartości, chociaż te dwa są luźno powiązane. Obiekt DateTime nie ma właściwości zwracającej obiekt reprezentujący strefę czasową tej wartości daty i godziny. Właściwość Kind wskazuje, czy DateTime
reprezentuje czas UTC, czas lokalny lub jest nieokreślony. W aplikacji obsługującej strefy czasowej należy opierać się na pewnym mechanizmie zewnętrznym, aby określić strefę czasową DateTime , w której został utworzony obiekt. Możesz użyć struktury, która obejmuje zarówno wartość DateTime, jak i obiekt TimeZoneInfo, który reprezentuje strefę czasową wartości DateTime. Aby uzyskać szczegółowe informacje na temat używania czasu UTC w obliczeniach i porównaniach z wartościami DateTime , zobacz Wykonywanie operacji arytmetycznych przy użyciu dat i godzin.
Każdy element DateTime niejawnie używa kalendarza gregoriańskiego do operacji. Wyjątki to metody, które niejawnie określają kalendarz. Obejmują one konstruktory, które określają kalendarz, i metody z parametrem pochodzącym z klasy IFormatProvider, takich jak System.Globalization.DateTimeFormatInfo.
Operacje wykonywane przez członków typu DateTime uwzględniają szczegóły, takie jak lata przestępne i liczba dni w miesiącu.
Wartości daty i czasu oraz kalendarze
Biblioteka klas platformy .NET zawiera wiele klas kalendarza, z których wszystkie pochodzą z Calendar klasy . Są to:
- Klasa ChineseLunisolarCalendar.
- Klasa EastAsianLunisolarCalendar.
- Klasa GregorianCalendar.
- Klasa HebrewCalendar.
- Klasa HijriCalendar.
- Klasa JapaneseCalendar.
- Klasa JapaneseLunisolarCalendar.
- Klasa JulianCalendar.
- Klasa KoreanCalendar.
- Klasa KoreanLunisolarCalendar.
- Klasa PersianCalendar.
- Klasa TaiwanCalendar.
- Klasa TaiwanLunisolarCalendar.
- Klasa ThaiBuddhistCalendar.
- Klasa UmAlQuraCalendar.
Ważne
Era w japońskich kalendarzach opiera się na panowaniu cesarza i dlatego oczekuje się, że się zmieni. Na przykład 1 maja 2019 r. oznaczało początek ery Reiwa w JapaneseCalendar i JapaneseLunisolarCalendar. Taka zmiana ery wpływa na wszystkie aplikacje korzystające z tych kalendarzy. Aby uzyskać więcej informacji i określić, czy twoje aplikacje mają wpływ, zobacz Obsługa nowej ery w kalendarzu japońskim na platformie .NET. Aby uzyskać informacje na temat testowania aplikacji w systemach Windows w celu zapewnienia gotowości do zmiany ery, zobacz Przygotowanie aplikacji do zmiany w erze japońskiej. Aby uzyskać informacje o funkcjach na platformie .NET, które obsługują kalendarze z wieloma epokami i aby uzyskać najlepsze rozwiązania dotyczące pracy z kalendarzami obsługującymi wiele epok, zobacz Praca z erami.
Każda kultura używa domyślnego kalendarza zdefiniowanego przez jej właściwość tylko do odczytu CultureInfo.Calendar. Każda kultura może obsługiwać jeden lub więcej kalendarzy zdefiniowanych przez swoją właściwość tylko do odczytu CultureInfo.OptionalCalendars. Kalendarz używany obecnie przez określony CultureInfo obiekt jest definiowany przez jego DateTimeFormatInfo.Calendar właściwość. Musi to być jeden z kalendarzy znalezionych w tablicy CultureInfo.OptionalCalendars .
Bieżący kalendarz kultury jest używany we wszystkich operacjach formatowania dla tej kultury. Na przykład domyślny kalendarz tajskiej kultury buddyjskiej to kalendarz tajskiej ery buddyjskiej, który jest reprezentowany przez klasę ThaiBuddhistCalendar . CultureInfo Gdy obiekt reprezentujący tajlandzką kulturę buddyjską jest używany w operacji formatowania daty i godziny, kalendarz tajskiej ery buddyjskiej jest domyślnie używany. Kalendarz gregoriański jest używany tylko wtedy, gdy właściwość kultury DateTimeFormatInfo.Calendar zostanie zmieniona, jak pokazano w poniższym przykładzie.
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
Bieżący kalendarz kultury jest również używany we wszystkich operacjach analizowania dla tej kultury, jak pokazano w poniższym przykładzie.
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
Tworzysz instancję DateTime wartości, korzystając z elementów daty i godziny (liczba roku, miesiąca i dnia) określonego kalendarza, poprzez wywołanie konstruktora DateTime, który zawiera calendar
parametr i przekazaniu mu obiektu reprezentującego ten Calendar kalendarz. W poniższym przykładzie użyto elementów daty i godziny z kalendarza ThaiBuddhistCalendar.
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, które nie zawierają parametru calendar
, zakładają, że elementy daty i godziny są wyrażone jako jednostki w kalendarzu gregoriańskim.
Wszystkie inne DateTime właściwości i metody używają kalendarza gregoriańskiego. Na przykład DateTime.Year właściwość zwraca rok w kalendarzu gregoriańskim, a DateTime.IsLeapYear(Int32) metoda zakłada, że year
parametr jest rokiem w kalendarzu gregoriańskim. Każdy DateTime element członkowski używający kalendarza gregoriańskiego ma odpowiedni element członkowski Calendar klasy używającej określonego kalendarza. Na przykład Calendar.GetYear metoda zwraca rok w określonym kalendarzu, a Calendar.IsLeapYear metoda interpretuje year
parametr jako numer roku w określonym kalendarzu. W poniższym przykładzie użyto zarówno DateTime, jak i odpowiadających im elementów klasy ThaiBuddhistCalendar.
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 zawiera właściwość zwracającą DayOfWeek dzień tygodnia w kalendarzu gregoriańskim. Nie zawiera elementu, który umożliwia odczytanie numeru tygodnia roku. Aby pobrać tydzień roku, wywołaj metodę poszczególnego kalendarza Calendar.GetWeekOfYear. Poniższy przykład stanowi ilustrację.
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
Aby uzyskać więcej informacji na temat dat i kalendarzy, zobacz Praca z kalendarzami.
Utrwalanie wartości daty/godziny
Wartości można utrwalać DateTime na następujące sposoby:
- Przekonwertuj je na ciągi i utrwalij ciągi.
- Przekonwertuj je na 64-bitowe wartości całkowite (wartość Ticks właściwości) i utrwały liczby całkowite.
- Serializowanie wartości DateTime.
Należy upewnić się, że rutyna, która przywraca DateTime wartości, nie traci danych ani nie zgłasza wyjątku niezależnie od wybranej techniki. DateTime wartości powinny pozostać niezmienione po powrocie. Oznacza to, że oryginalna wartość i przywrócona wartość powinny być takie same. A jeśli oryginalna DateTime wartość reprezentuje pojedynczy moment w czasie, powinna identyfikować ten sam moment w czasie, gdy zostanie przywrócona.
Utrwalaj wartości jako ciągi znaków
Aby pomyślnie przywrócić DateTime wartości utrwalone jako ciągi, wykonaj następujące reguły:
Należy przyjąć te same założenia dotyczące formatowania specyficznego dla kultury podczas przywracania ciągu, co podczas jego utrwalania. Aby upewnić się, że ciąg można przywrócić w systemie, którego bieżąca kultura różni się od kultury systemu, na którym został zapisany, wywołaj wersję przeciążonej funkcji ToString, aby zapisać ciąg według konwencji niezmiennej kultury. Wywołaj metodę Parse(String, IFormatProvider, DateTimeStyles) lub TryParse(String, IFormatProvider, DateTimeStyles, DateTime), aby przywrócić tekst zgodnie z zasadami kultury niezmiennej. Nigdy nie używaj przeciążeń ToString(), Parse(String) lub TryParse(String, DateTime), które wykorzystują konwencje bieżącej kultury.
Jeśli data reprezentuje pojedynczą chwilę czasu, upewnij się, że reprezentuje ona ten sam moment w czasie, gdy zostanie przywrócona, nawet w innej strefie czasowej. Przekonwertuj DateTime wartość na uniwersalny czas koordynowany (UTC) przed zapisaniem go lub użyj polecenia DateTimeOffset.
Najczęstszym błędem występującym podczas utrwalania DateTime wartości jako ciągów jest poleganie na konwencjach formatowania domyślnej lub bieżącej kultury. Występują problemy, jeśli bieżąca kultura jest inna podczas zapisywania lub przywracania ciągów. Poniższy przykład ilustruje te problemy. Zapisuje pięć dat przy użyciu konwencji formatowania bieżącej kultury, która w tym przypadku jest angielska (Stany Zjednoczone). Przywraca daty przy użyciu konwencji formatowania innej kultury, która w tym przypadku jest angielska (Wielka Brytania). Ponieważ konwencje formatowania dwóch kultur są różne, nie można przywrócić dwóch dat, a pozostałe trzy daty są interpretowane niepoprawnie. Ponadto jeśli oryginalne wartości daty i godziny reprezentują pojedyncze momenty w czasie, przywrócone czasy są niepoprawne, ponieważ informacje o strefie czasowej zostaną utracone.
public static void PersistAsLocalStrings()
{
SaveLocalDatesAsString();
RestoreLocalDatesFromString();
}
private static void SaveLocalDatesAsString()
{
DateTime[] dates = { new DateTime(2014, 6, 14, 6, 32, 0),
new DateTime(2014, 7, 10, 23, 49, 0),
new DateTime(2015, 1, 10, 1, 16, 0),
new DateTime(2014, 12, 20, 21, 45, 0),
new DateTime(2014, 6, 2, 15, 14, 0) };
string? output = null;
Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}");
Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:");
for (int ctr = 0; ctr < dates.Length; ctr++)
{
Console.WriteLine(dates[ctr].ToString("f"));
output += dates[ctr].ToString() + (ctr != dates.Length - 1 ? "|" : "");
}
var sw = new StreamWriter(filenameTxt);
sw.Write(output);
sw.Close();
Console.WriteLine("Saved dates...");
}
private static void RestoreLocalDatesFromString()
{
TimeZoneInfo.ClearCachedData();
Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}");
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB");
StreamReader sr = new StreamReader(filenameTxt);
string[] inputValues = sr.ReadToEnd().Split(new char[] { '|' },
StringSplitOptions.RemoveEmptyEntries);
sr.Close();
Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:");
foreach (var inputValue in inputValues)
{
DateTime dateValue;
if (DateTime.TryParse(inputValue, out dateValue))
{
Console.WriteLine($"'{inputValue}' --> {dateValue:f}");
}
else
{
Console.WriteLine($"Cannot parse '{inputValue}'");
}
}
Console.WriteLine("Restored dates...");
}
// When saved on an en-US system, the example displays the following output:
// Current Time Zone: (UTC-08:00) Pacific Time (US & Canada)
// The dates on an en-US system:
// Saturday, June 14, 2014 6:32 AM
// Thursday, July 10, 2014 11:49 PM
// Saturday, January 10, 2015 1:16 AM
// Saturday, December 20, 2014 9:45 PM
// Monday, June 02, 2014 3:14 PM
// Saved dates...
//
// When restored on an en-GB system, the example displays the following output:
// Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London
// The dates on an en-GB system:
// Cannot parse //6/14/2014 6:32:00 AM//
// //7/10/2014 11:49:00 PM// --> 07 October 2014 23:49
// //1/10/2015 1:16:00 AM// --> 01 October 2015 01:16
// Cannot parse //12/20/2014 9:45:00 PM//
// //6/2/2014 3:14:00 PM// --> 06 February 2014 15:14
// Restored dates...
let saveLocalDatesAsString () =
let dates =
[ DateTime(2014, 6, 14, 6, 32, 0)
DateTime(2014, 7, 10, 23, 49, 0)
DateTime(2015, 1, 10, 1, 16, 0)
DateTime(2014, 12, 20, 21, 45, 0)
DateTime(2014, 6, 2, 15, 14, 0) ]
printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"
printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"
let output =
[ for date in dates do
printfn $"{date}"
string date ]
|> String.concat "|"
use sw = new StreamWriter(filenameTxt)
sw.Write output
printfn "Saved dates..."
let restoreLocalDatesFromString () =
TimeZoneInfo.ClearCachedData()
printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"
Thread.CurrentThread.CurrentCulture <- CultureInfo.CreateSpecificCulture "en-GB"
use sr = new StreamReader(filenameTxt)
let inputValues =
sr.ReadToEnd().Split('|', StringSplitOptions.RemoveEmptyEntries)
printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"
for inputValue in inputValues do
match DateTime.TryParse inputValue with
| true, dateValue ->
printfn $"'{inputValue}' --> {dateValue:f}"
| _ ->
printfn $"Cannot parse '{inputValue}'"
printfn "Restored dates..."
let persistAsLocalStrings () =
saveLocalDatesAsString ()
restoreLocalDatesFromString ()
// When saved on an en-US system, the example displays the following output:
// Current Time Zone: (UTC-08:00) Pacific Time (US & Canada)
// The dates on an en-US system:
// Saturday, June 14, 2014 6:32 AM
// Thursday, July 10, 2014 11:49 PM
// Saturday, January 10, 2015 1:16 AM
// Saturday, December 20, 2014 9:45 PM
// Monday, June 02, 2014 3:14 PM
// Saved dates...
//
// When restored on an en-GB system, the example displays the following output:
// Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London
// The dates on an en-GB system:
// Cannot parse //6/14/2014 6:32:00 AM//
// //7/10/2014 11:49:00 PM// --> 07 October 2014 23:49
// //1/10/2015 1:16:00 AM// --> 01 October 2015 01:16
// Cannot parse //12/20/2014 9:45:00 PM//
// //6/2/2014 3:14:00 PM// --> 06 February 2014 15:14
// Restored dates...
Aby pomyślnie zaokrąglić DateTime wartości, wykonaj następujące kroki:
- Jeśli wartości reprezentują pojedyncze chwile czasu, przekonwertuj je z czasu lokalnego na UTC, wywołując metodę ToUniversalTime .
- Przekonwertuj daty na ich reprezentacje łańcuchów, wywołując przeciążenie ToString(String, IFormatProvider) lub String.Format(IFormatProvider, String, Object[]). Użyj konwencji formatowania niezmiennej kultury, podając CultureInfo.InvariantCulture jako argument
provider
. Określ, że wartość powinna być zaokrąglana przy użyciu standardowego ciągu formatu "O" lub "R".
Aby przywrócić utrwalone DateTime wartości bez utraty danych, wykonaj następujące kroki:
- Przeanalizuj dane, wywołując przeciążenie ParseExact lub TryParseExact. Określ CultureInfo.InvariantCulture jako
provider
argument i użyj tego samego standardowego ciągu formatu, który został użyty dla argumentuformat
podczas konwersji. Uwzględnij wartość DateTimeStyles.RoundtripKind w argumenciestyles
. - DateTime Jeśli wartości reprezentują pojedyncze momenty w czasie, wywołaj metodę ToLocalTime , aby przekonwertować przeanalizowaną datę z czasu UTC na czas lokalny.
W poniższym przykładzie użyto niezmiennej kultury i standardowego ciągu formatu "O", aby upewnić się, że DateTime wartości zapisane i przywrócone reprezentują ten sam moment w czasie, niezależnie od systemu, kultury lub strefy czasowej systemów źródłowych i docelowych.
public static void PersistAsInvariantStrings()
{
SaveDatesAsInvariantStrings();
RestoreDatesAsInvariantStrings();
}
private static void SaveDatesAsInvariantStrings()
{
DateTime[] dates = { new DateTime(2014, 6, 14, 6, 32, 0),
new DateTime(2014, 7, 10, 23, 49, 0),
new DateTime(2015, 1, 10, 1, 16, 0),
new DateTime(2014, 12, 20, 21, 45, 0),
new DateTime(2014, 6, 2, 15, 14, 0) };
string? output = null;
Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}");
Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:");
for (int ctr = 0; ctr < dates.Length; ctr++)
{
Console.WriteLine(dates[ctr].ToString("f"));
output += dates[ctr].ToUniversalTime().ToString("O", CultureInfo.InvariantCulture)
+ (ctr != dates.Length - 1 ? "|" : "");
}
var sw = new StreamWriter(filenameTxt);
sw.Write(output);
sw.Close();
Console.WriteLine("Saved dates...");
}
private static void RestoreDatesAsInvariantStrings()
{
TimeZoneInfo.ClearCachedData();
Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}");
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB");
StreamReader sr = new StreamReader(filenameTxt);
string[] inputValues = sr.ReadToEnd().Split(new char[] { '|' },
StringSplitOptions.RemoveEmptyEntries);
sr.Close();
Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:");
foreach (var inputValue in inputValues)
{
DateTime dateValue;
if (DateTime.TryParseExact(inputValue, "O", CultureInfo.InvariantCulture,
DateTimeStyles.RoundtripKind, out dateValue))
{
Console.WriteLine($"'{inputValue}' --> {dateValue.ToLocalTime():f}");
}
else
{
Console.WriteLine($"Cannot parse '{inputValue}'");
}
}
Console.WriteLine("Restored dates...");
}
// When saved on an en-US system, the example displays the following output:
// Current Time Zone: (UTC-08:00) Pacific Time (US & Canada)
// The dates on an en-US system:
// Saturday, June 14, 2014 6:32 AM
// Thursday, July 10, 2014 11:49 PM
// Saturday, January 10, 2015 1:16 AM
// Saturday, December 20, 2014 9:45 PM
// Monday, June 02, 2014 3:14 PM
// Saved dates...
//
// When restored on an en-GB system, the example displays the following output:
// Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London
// The dates on an en-GB system:
// '2014-06-14T13:32:00.0000000Z' --> 14 June 2014 14:32
// '2014-07-11T06:49:00.0000000Z' --> 11 July 2014 07:49
// '2015-01-10T09:16:00.0000000Z' --> 10 January 2015 09:16
// '2014-12-21T05:45:00.0000000Z' --> 21 December 2014 05:45
// '2014-06-02T22:14:00.0000000Z' --> 02 June 2014 23:14
// Restored dates...
let saveDatesAsInvariantStrings () =
let dates =
[ DateTime(2014, 6, 14, 6, 32, 0)
DateTime(2014, 7, 10, 23, 49, 0)
DateTime(2015, 1, 10, 1, 16, 0)
DateTime(2014, 12, 20, 21, 45, 0)
DateTime(2014, 6, 2, 15, 14, 0) ]
printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"
printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"
let output =
[ for date in dates do
printfn $"{date:f}"
date.ToUniversalTime().ToString("O", CultureInfo.InvariantCulture) ]
|> String.concat "|"
use sw = new StreamWriter(filenameTxt)
sw.Write output
printfn "Saved dates..."
let restoreDatesAsInvariantStrings () =
TimeZoneInfo.ClearCachedData()
printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"
Thread.CurrentThread.CurrentCulture <- CultureInfo.CreateSpecificCulture "en-GB"
use sr = new StreamReader(filenameTxt)
let inputValues =
sr.ReadToEnd().Split('|', StringSplitOptions.RemoveEmptyEntries)
printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"
for inputValue in inputValues do
match DateTime.TryParseExact(inputValue, "O", CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind) with
| true, dateValue ->
printfn $"'{inputValue}' --> {dateValue.ToLocalTime():f}"
| _ ->
printfn $"Cannot parse '{inputValue}'"
printfn "Restored dates..."
let persistAsInvariantStrings () =
saveDatesAsInvariantStrings ()
restoreDatesAsInvariantStrings ()
// When saved on an en-US system, the example displays the following output:
// Current Time Zone: (UTC-08:00) Pacific Time (US & Canada)
// The dates on an en-US system:
// Saturday, June 14, 2014 6:32 AM
// Thursday, July 10, 2014 11:49 PM
// Saturday, January 10, 2015 1:16 AM
// Saturday, December 20, 2014 9:45 PM
// Monday, June 02, 2014 3:14 PM
// Saved dates...
//
// When restored on an en-GB system, the example displays the following output:
// Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London
// The dates on an en-GB system:
// '2014-06-14T13:32:00.0000000Z' --> 14 June 2014 14:32
// '2014-07-11T06:49:00.0000000Z' --> 11 July 2014 07:49
// '2015-01-10T09:16:00.0000000Z' --> 10 January 2015 09:16
// '2014-12-21T05:45:00.0000000Z' --> 21 December 2014 05:45
// '2014-06-02T22:14:00.0000000Z' --> 02 June 2014 23:14
// Restored dates...
Utrwalanie wartości jako liczby całkowite
Możesz zapisać datę i godzinę jako wartość Int64, która reprezentuje liczbę tików. W takim przypadku nie trzeba brać pod uwagę kultury systemów, na DateTime których są utrwalane i przywracane wartości.
Aby utrwałyć DateTime wartość jako liczbę całkowitą:
- DateTime Jeśli wartości reprezentują pojedyncze chwile w czasie, przekonwertuj je na utc, wywołując metodę ToUniversalTime .
- Pobierz liczbę znaczników reprezentowaną przez wartość DateTime z właściwości Ticks.
Aby przywrócić wartość DateTime, która została zapisana jako liczba całkowita:
- Utwórz nowe wystąpienie obiektu DateTime, przekazując wartość Int64 do konstruktora DateTime(Int64).
- DateTime Jeśli wartość reprezentuje pojedynczą chwilę w czasie, przekonwertuj ją z czasu UTC na czas lokalny, wywołując metodę ToLocalTime .
W poniższym przykładzie tablica wartości DateTime jest utrwalana jako liczby całkowite w systemie w strefie czasowej Pacyfiku USA. Przywraca dane do systemu z ustawioną strefą czasową UTC. Plik zawierający liczby całkowite zawiera wartość Int32, która wskazuje całkowitą liczbę wartości Int64, które natychmiast po niej następują.
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...
Serializowanie wartości DateTime
Wartości można utrwalać za pomocą serializacji do strumienia lub pliku, a następnie przywrócić je za pomocą deserializacji. DateTime dane są serializowane w określonym formacie obiektu. Obiekty są przywracane podczas deserializacji. Formatator lub serializator, taki jak JsonSerializer lub XmlSerializer, obsługuje proces serializacji i deserializacji. Aby uzyskać więcej informacji na temat serializacji i typów serializacji obsługiwanych przez platformę .NET, zobacz Serializacja.
W poniższym przykładzie użyto XmlSerializer klasy do serializacji i deserializacji DateTime wartości. Wartości reprezentują wszystkie dni roku przestępnego w XXI wieku. Dane wyjściowe reprezentują wynik, jeśli przykład jest uruchamiany w systemie, którego bieżąca kultura to angielski (Wielka Brytania). Ponieważ zdeserializowałeś sam obiekt DateTime, kod nie musi obsługiwać różnic kulturowych w formatach daty i godziny.
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
Poprzedni przykład nie zawiera informacji o czasie. DateTime Jeśli wartość reprezentuje moment w czasie i jest wyrażona jako czas lokalny, przekonwertuj ją z czasu lokalnego na UTC przed serializacji, wywołując metodę ToUniversalTime . Po deserializacji przekonwertuj ją z czasu UTC na czas lokalny, wywołując metodę ToLocalTime .
DateTime a TimeSpan
Typy DateTime wartości i TimeSpan różnią się tym, że DateTime reprezentuje moment w czasie, podczas gdy TimeSpan reprezentuje interwał czasu. Można odjąć jedno wystąpienie DateTime z innego, aby uzyskać TimeSpan obiekt reprezentujący przedział czasu między nimi. Możesz też dodać wynik dodatni TimeSpan do bieżącego DateTime , aby uzyskać DateTime wartość reprezentującą przyszłą datę.
Możesz dodać lub odjąć interwał czasu z DateTime obiektu. Przedziały czasu mogą być ujemne lub dodatnie i mogą być wyrażone w jednostkach, takich jak znaczniki, sekundy lub jako TimeSpan obiekt.
Porównaj pod kątem równości z uwzględnieniem tolerancji
Porównania równości wartości DateTime są dokładne. Aby uznać za równe, dwie wartości muszą być wyrażone jako ta sama liczba kleszczy. Ta precyzja jest często niepotrzebna lub nawet niepoprawna dla wielu aplikacji. Często chcesz sprawdzić, czy DateTime obiekty są w przybliżeniu równe.
W poniższym przykładzie pokazano, jak porównać mniej więcej równoważne DateTime wartości. Przyjmuje niewielki margines różnicy przy deklarowaniu ich jako równych.
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
Zagadnienia dotyczące interoperacyjności modelu COM
Wartość DateTime, która jest przekazywana do aplikacji COM, a następnie przenoszona z powrotem do aplikacji zarządzanej, jest określana jako obiegowa. Jednak wartość DateTime określająca tylko czas nie pozwala na ponowne konwertowanie zgodnie z oczekiwaniami.
Jeśli określona jest tylko godzina, na przykład 13:00, ostateczna data i godzina to 30 grudnia 1899 n.e. o godzinie 13:00, zamiast 1 stycznia 0001 n.e. o godzinie 13:00. .NET i COM zakładają domyślną datę, gdy określona jest tylko godzina. Jednak system COM zakłada datę bazową 30 grudnia 1899 R., podczas gdy platforma .NET zakłada datę bazową 1 stycznia 0001 R.
Gdy tylko czas jest przekazywany z platformy .NET do modelu COM, wykonywane jest specjalne przetwarzanie, które konwertuje czas na format używany przez com. Gdy z modelu COM do platformy .NET przekazywany jest jedynie czas, nie jest wykonywane żadne specjalne przetwarzanie, ponieważ mogłoby to uszkodzić prawidłowe daty i godziny z dnia 30 grudnia 1899 r. lub wcześniejsze. Jeśli data rozpoczyna swoją podróż okrężną z COM, .NET i COM zachowują datę.
Zachowanie platformy .NET i modelu COM oznacza, że jeśli Twoja aplikacja przetwarza obiekt DateTime, który określa tylko godzinę, musi pamiętać o zmodyfikowaniu lub zignorowaniu błędnej daty w końcowym obiekcie DateTime.