Como aplicar uma viagem de ida e volta para valores de data e hora
Em muitos aplicativos, um valor de data e hora destina-se a identificar sem ambiguidade um único ponto no tempo. Este artigo mostra como salvar e restaurar um valor DateTime, um valor DateTimeOffset e um valor de data e hora com informações de fuso horário para que o valor restaurado identifique a mesma hora que o valor salvo.
Ida e volta de um valor DateTime
Converta o valor DateTime em sua representação de cadeia de caracteres chamando o método DateTime.ToString(String) com o especificador de formato "o".
Salve a representação de cadeia de caracteres do valor DateTime em um arquivo ou passe-a por um processo, domínio de aplicativo ou limite de computador.
Recupere a cadeia de caracteres que representa o valor DateTime.
Chame o método DateTime.Parse(String, IFormatProvider, DateTimeStyles) e passe DateTimeStyles.RoundtripKind como o valor do parâmetro
styles
.
O exemplo a seguir mostra como fazer a viagem de ida e volta de um valor DateTime.
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.
Fazendo a viagem de ida e volta de um valor DateTime, essa técnica consegue preservar o horário para todos os horários locais e universais. Por exemplo, se um valor DateTime local for salvo em um sistema no fuso horário padrão do Pacífico dos EUA e for restaurado em um sistema no fuso horário padrão central dos EUA, a data e a hora restauradas serão duas horas depois do horário original , que reflete a diferença horária entre os dois fusos horários. No entanto, essa técnica não é necessariamente exata para horários não especificados. Todos os valores DateTime cuja propriedade Kind é Unspecified são tratados como se fossem horários locais. Se não for uma hora local, o DateTime não identifica com êxito o momento correto. A solução alternativa para essa limitação é acoplar rigorosamente um valor de data e hora com seu fuso horário para salvar e restaurar a operação.
Ida e volta de um valor DateTimeOffset
Converta o valor DateTimeOffset em sua representação de cadeia de caracteres chamando o método DateTimeOffset.ToString(String) com o especificador de formato "o".
Salve a representação de cadeia de caracteres do valor DateTimeOffset em um arquivo ou passe-a por um processo, domínio de aplicativo ou limite de computador.
Recupere a cadeia de caracteres que representa o valor DateTimeOffset.
Chame o método DateTimeOffset.Parse(String, IFormatProvider, DateTimeStyles) e passe DateTimeStyles.RoundtripKind como o valor do parâmetro
styles
.
O exemplo a seguir mostra como fazer a viagem de ida e volta de um valor DateTimeOffset.
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.
Essa técnica sempre identifica sem ambiguidade um valor DateTimeOffset como um único momento. O valor pode ser convertido em UTC (Tempo Universal Coordenado) chamando o método DateTimeOffset.ToUniversalTime ou pode ser convertido em determinado fuso horário chamando o método DateTimeOffset.ToOffset ou TimeZoneInfo.ConvertTime(DateTimeOffset, TimeZoneInfo). A principal limitação dessa técnica é que a aritmética de data e hora, quando executada em um valor DateTimeOffset que representa o horário em determinado fuso horário, talvez não produza resultados precisos para esse fuso horário. Isso ocorre porque, quando um valor DateTimeOffset é instanciado, é dissociado do fuso horário. Portanto, as regras de ajuste do fuso horário não podem mais ser aplicadas quando você executa cálculos de data e hora. É possível solucionar esse problema definindo um tipo personalizado que inclui um valor de data e hora e o respectivo fuso horário.
Compilar o código
Esses exemplos exigem que os seguintes namespaces podem ser importados com diretivas C# using
ou instruções Visual Basic Imports
:
- System (somente C#)
- System.Globalization
- System.IO