Instrukcje: wartości daty i godziny w obie strony

W wielu aplikacjach wartość daty i godziny jest przeznaczona do jednoznacznego identyfikowania pojedynczego punktu w czasie. W tym artykule pokazano, jak zapisać i przywrócić DateTime wartość, DateTimeOffset wartość oraz wartość daty i godziny z informacjami o strefie czasowej, aby przywrócona wartość identyfikowała ten sam czas co zapisana wartość.

Round-trip a DateTime value (Zaokrągla wartość typu Data/godzina)

  1. Przekonwertuj wartość na reprezentację DateTime ciągu, wywołując metodę DateTime.ToString(String) za pomocą specyfikatora formatu "o".

  2. Zapisz ciąg reprezentujący DateTime wartość w pliku lub przekaż go przez proces, domenę aplikacji lub granicę maszyny.

  3. Pobierz ciąg reprezentujący DateTime wartość.

  4. Wywołaj metodę DateTime.Parse(String, IFormatProvider, DateTimeStyles) i przekaż DateTimeStyles.RoundtripKind jako wartość parametru styles .

W poniższym przykładzie pokazano, jak zaokrąglić DateTime wartość.

const string fileName = @".\DateFile.txt";

StreamWriter outFile = new StreamWriter(fileName);

// Save DateTime value.
DateTime dateToSave = DateTime.SpecifyKind(new DateTime(2008, 6, 12, 18, 45, 15),
                                           DateTimeKind.Local);
string? dateString = dateToSave.ToString("o");
Console.WriteLine("Converted {0} ({1}) to {2}.",
                  dateToSave.ToString(),
                  dateToSave.Kind.ToString(),
                  dateString);
outFile.WriteLine(dateString);
Console.WriteLine("Wrote {0} to {1}.", dateString, fileName);
outFile.Close();

// Restore DateTime value.
DateTime restoredDate;

using StreamReader inFile = new StreamReader(fileName);
dateString = inFile.ReadLine();

if (dateString is not null)
{
    restoredDate = DateTime.Parse(dateString, null, DateTimeStyles.RoundtripKind);
    Console.WriteLine("Read {0} ({2}) from {1}.", restoredDate.ToString(),
                                                  fileName,
                                                  restoredDate.Kind.ToString());
}

// The example displays the following output:
//    Converted 6/12/2008 6:45:15 PM (Local) to 2008-06-12T18:45:15.0000000-05:00.
//    Wrote 2008-06-12T18:45:15.0000000-05:00 to .\DateFile.txt.
//    Read 6/12/2008 6:45:15 PM (Local) from .\DateFile.txt.
Const fileName As String = ".\DateFile.txt"

Dim outFile As New StreamWriter(fileName)

' Save DateTime value.
Dim dateToSave As Date = DateTime.SpecifyKind(#06/12/2008 6:45:15 PM#, _
                                              DateTimeKind.Local)
Dim dateString As String = dateToSave.ToString("o")
Console.WriteLine("Converted {0} ({1}) to {2}.", dateToSave.ToString(), _
                  dateToSave.Kind.ToString(), dateString)
outFile.WriteLine(dateString)
Console.WriteLine("Wrote {0} to {1}.", dateString, fileName)
outFile.Close()

' Restore DateTime value.
Dim restoredDate As Date

Dim inFile As New StreamReader(fileName)
dateString = inFile.ReadLine()
inFile.Close()
restoredDate = DateTime.Parse(dateString, Nothing, DateTimeStyles.RoundTripKind)
Console.WriteLine("Read {0} ({2}) from {1}.", restoredDate.ToString(), _
                  fileName, restoredDAte.Kind.ToString())
' The example displays the following output:
'    Converted 6/12/2008 6:45:15 PM (Local) to 2008-06-12T18:45:15.0000000-05:00.
'    Wrote 2008-06-12T18:45:15.0000000-05:00 to .\DateFile.txt.
'    Read 6/12/2008 6:45:15 PM (Local) from .\DateFile.txt.

W przypadku zaokrąglania DateTime wartości ta technika pomyślnie zachowuje czas dla wszystkich lokalnych i uniwersalnych czasów. Jeśli na przykład wartość lokalna DateTime jest zapisywana w systemie w strefie czasowej Pacyfik pacyficzny (standardowy) USA i zostanie przywrócona w systemie w centralnej strefie czasowej w USA, przywrócona data i godzina będą dwie godziny później niż oryginalna godzina, co odzwierciedla różnicę czasu między dwiema strefami czasowymi. Jednak ta technika nie musi być dokładna dla nieokreślonych czasów. Wszystkie DateTime wartości, których Kind właściwość jest Unspecified traktowana tak, jakby były to czasy lokalne. Jeśli nie jest to czas lokalny, DateTime funkcja nie identyfikuje poprawnego punktu w czasie. Obejściem tego ograniczenia jest ścisłe połączenie wartości daty i godziny ze strefą czasową dla operacji zapisywania i przywracania.

Round-trip a DateTimeOffset wartość

  1. Przekonwertuj wartość na reprezentację DateTimeOffset ciągu, wywołując metodę DateTimeOffset.ToString(String) za pomocą specyfikatora formatu "o".

  2. Zapisz ciąg reprezentujący DateTimeOffset wartość w pliku lub przekaż go przez proces, domenę aplikacji lub granicę maszyny.

  3. Pobierz ciąg reprezentujący DateTimeOffset wartość.

  4. Wywołaj metodę DateTimeOffset.Parse(String, IFormatProvider, DateTimeStyles) i przekaż DateTimeStyles.RoundtripKind jako wartość parametru styles .

W poniższym przykładzie pokazano, jak zaokrąglić DateTimeOffset wartość.

const string fileName = @".\DateOff.txt";

StreamWriter outFile = new StreamWriter(fileName);

// Save DateTime value.
DateTimeOffset dateToSave = new DateTimeOffset(2008, 6, 12, 18, 45, 15,
                                               new TimeSpan(7, 0, 0));
string? dateString = dateToSave.ToString("o");
Console.WriteLine("Converted {0} to {1}.", dateToSave.ToString(),
                  dateString);
outFile.WriteLine(dateString);
Console.WriteLine("Wrote {0} to {1}.", dateString, fileName);
outFile.Close();

// Restore DateTime value.
DateTimeOffset restoredDateOff;

using StreamReader inFile = new StreamReader(fileName);
dateString = inFile.ReadLine();

if (dateString is not null)
{
    restoredDateOff = DateTimeOffset.Parse(dateString, null,
                                           DateTimeStyles.RoundtripKind);
    Console.WriteLine("Read {0} from {1}.", restoredDateOff.ToString(), fileName);
}

// The example displays the following output:
//    Converted 6/12/2008 6:45:15 PM +07:00 to 2008-06-12T18:45:15.0000000+07:00.
//    Wrote 2008-06-12T18:45:15.0000000+07:00 to .\DateOff.txt.
//    Read 6/12/2008 6:45:15 PM +07:00 from .\DateOff.txt.
Const fileName As String = ".\DateOff.txt"

Dim outFile As New StreamWriter(fileName)

' Save DateTime value.
Dim dateToSave As New DateTimeOffset(2008, 6, 12, 18, 45, 15, _
                                     New TimeSpan(7, 0, 0))
Dim dateString As String = dateToSave.ToString("o")
Console.WriteLine("Converted {0} to {1}.", dateToSave.ToString(), dateString)
outFile.WriteLine(dateString)
Console.WriteLine("Wrote {0} to {1}.", dateString, fileName)
outFile.Close()

' Restore DateTime value.
Dim restoredDateOff As DateTimeOffset

Dim inFile As New StreamReader(fileName)
dateString = inFile.ReadLine()
inFile.Close()
restoredDateOff = DateTimeOffset.Parse(dateString, Nothing, DateTimeStyles.RoundTripKind)
Console.WriteLine("Read {0} from {1}.", restoredDateOff.ToString(), fileName)
' The example displays the following output:
'    Converted 6/12/2008 6:45:15 PM +07:00 to 2008-06-12T18:45:15.0000000+07:00.
'    Wrote 2008-06-12T18:45:15.0000000+07:00 to .\DateOff.txt.
'    Read 6/12/2008 6:45:15 PM +07:00 from .\DateOff.txt.

Ta technika zawsze jednoznacznie identyfikuje DateTimeOffset wartość jako pojedynczy punkt w czasie. Wartość można następnie przekonwertować na uniwersalny czas koordynowany (UTC) przez wywołanie DateTimeOffset.ToUniversalTime metody lub można ją przekonwertować na godzinę w określonej strefie czasowej, wywołując DateTimeOffset.ToOffset metodę or TimeZoneInfo.ConvertTime(DateTimeOffset, TimeZoneInfo) . Głównym ograniczeniem tej techniki jest to, że arytmetyka daty i godziny, podczas wykonywania na DateTimeOffset wartości reprezentującej godzinę w określonej strefie czasowej, może nie generować dokładnych wyników dla tej strefy czasowej. Jest to spowodowane tym, że po utworzeniu DateTimeOffset wystąpienia wartości jest ona odłączona od strefy czasowej. W związku z tym reguły korekty tej strefy czasowej nie mogą być już stosowane podczas wykonywania obliczeń daty i godziny. Ten problem można obejść, definiując typ niestandardowy, który zawiera zarówno wartość daty, jak i godziny oraz towarzyszące jej strefy czasowej.

Kompilowanie kodu

Te przykłady wymagają zaimportowania następujących przestrzeni nazw z dyrektywami języka C# using lub instrukcjami języka Visual Basic Imports :

Zobacz też