如何:往返日期和时间值
在许多应用程序中,日期和时间值旨在明确标识单个时间点。 本文演示了如何保存和还原 DateTime 值、DateTimeOffset 值以及包含时区信息的日期和时间值,以便还原后的值与保存的值标识的时间相同。
往返 DateTime 值
通过调用包含 "o" 格式说明符的 DateTime.ToString(String) 方法,将 DateTime 值转换为字符串表示形式。
将 DateTime 值的字符串表示形式保存到文件中,或跨进程、应用域或计算机边界传递它。
检索表示 DateTime 值的字符串。
调用 DateTime.Parse(String, IFormatProvider, DateTimeStyles) 方法,并以
styles
参数值的形式传递 DateTimeStyles.RoundtripKind。
下面的示例展示了如何往返 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.
往返 DateTime 值时,此方法成功暂留所有本地时间和世界时间。 例如,如果本地 DateTime 值保存在采用美国太平洋标准时区的系统会,并在位于美国中部标准时区的系统上还原,则还原的日期和时间会比原始时间晚两个小时,这反映了两个时区之间的时差。 但是,此方法对于未指定时间不一定准确。 所有 Kind 属性为 Unspecified 的 DateTime 值都会被视为本地时间。 如果不是本地时间,则 DateTime 不会成功标识正确的时间点。 针对此限制的解决方法是将日期和时间值与其时区紧密耦合,以便进行保存和还原操作。
往返 DateTimeOffset 值
通过调用包含 "o" 格式说明符的 DateTimeOffset.ToString(String) 方法,将 DateTimeOffset 值转换为字符串表示形式。
将 DateTimeOffset 值的字符串表示形式保存到文件中,或跨进程、应用域或计算机边界传递它。
检索表示 DateTimeOffset 值的字符串。
调用 DateTimeOffset.Parse(String, IFormatProvider, DateTimeStyles) 方法,并以
styles
参数值的形式传递 DateTimeStyles.RoundtripKind。
下面的示例展示了如何往返 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.
此方法始终将 DateTimeOffset 值明确标识为单个时间点。 然后,可以调用 DateTimeOffset.ToUniversalTime 方法,将此值转换为协调世界时 (UTC);也可以调用 DateTimeOffset.ToOffset 或 TimeZoneInfo.ConvertTime(DateTimeOffset, TimeZoneInfo) 方法,将此值转换为特定时区时间。 此方法的主要限制在于,如果对表示特定时区时间的 DateTimeOffset 值执行日期和时间算术,生成的结果对于相应时区来说可能并不准确。 这是因为 DateTimeOffset 值在实例化时就与时区解除关联。 因此,执行日期和时间计算时,无法再应用该时区的调整规则。 可以通过定义包含日期和时间值以及其随附时区的自定义类型,来解决此问题。
编译代码
这些示例要求使用 C# using
指令或 Visual Basic Imports
语句导入下列命名空间:
- System(仅限 C#)
- System.Globalization
- System.IO