DateTime 结构

定义

表示时间上的一刻,通常以日期和当天的时间表示。

public value class DateTime : IComparable, IComparable<DateTime>, IConvertible, IEquatable<DateTime>, IFormattable
public value class DateTime : IComparable, IComparable<DateTime>, IConvertible, IEquatable<DateTime>, IFormattable, System::Runtime::Serialization::ISerializable
public value class DateTime : IComparable, IComparable<DateTime>, IConvertible, IEquatable<DateTime>, ISpanFormattable, System::Runtime::Serialization::ISerializable
public value class DateTime : IAdditionOperators<DateTime, TimeSpan, DateTime>, IAdditiveIdentity<DateTime, TimeSpan>, IComparable<DateTime>, IComparisonOperators<DateTime, DateTime>, IConvertible, IEqualityOperators<DateTime, DateTime>, IEquatable<DateTime>, IMinMaxValue<DateTime>, IParseable<DateTime>, ISpanFormattable, ISpanParseable<DateTime>, ISubtractionOperators<DateTime, DateTime, TimeSpan>, ISubtractionOperators<DateTime, TimeSpan, DateTime>, System::Runtime::Serialization::ISerializable
public value class DateTime : IComparable, IConvertible, IFormattable
public value class DateTime : IComparable, IComparable<DateTime>, IEquatable<DateTime>, IFormattable
public struct DateTime : IComparable, IComparable<DateTime>, IConvertible, IEquatable<DateTime>, IFormattable
public readonly struct DateTime : IComparable, IComparable<DateTime>, IConvertible, IEquatable<DateTime>, IFormattable, System.Runtime.Serialization.ISerializable
public readonly struct DateTime : IComparable, IComparable<DateTime>, IConvertible, IEquatable<DateTime>, ISpanFormattable, System.Runtime.Serialization.ISerializable
public readonly struct DateTime : IAdditionOperators<DateTime,TimeSpan,DateTime>, IAdditiveIdentity<DateTime,TimeSpan>, IComparable<DateTime>, IComparisonOperators<DateTime,DateTime>, IConvertible, IEqualityOperators<DateTime,DateTime>, IEquatable<DateTime>, IMinMaxValue<DateTime>, IParseable<DateTime>, ISpanFormattable, ISpanParseable<DateTime>, ISubtractionOperators<DateTime,DateTime,TimeSpan>, ISubtractionOperators<DateTime,TimeSpan,DateTime>, System.Runtime.Serialization.ISerializable
public struct DateTime : IComparable, IComparable<DateTime>, IConvertible, IEquatable<DateTime>, IFormattable, System.Runtime.Serialization.ISerializable
[System.Serializable]
public struct DateTime : IComparable, IConvertible, IFormattable
[System.Serializable]
public struct DateTime : IComparable, IComparable<DateTime>, IConvertible, IEquatable<DateTime>, IFormattable, System.Runtime.Serialization.ISerializable
public struct DateTime : IComparable, IComparable<DateTime>, IEquatable<DateTime>, IFormattable
type DateTime = struct
    interface IConvertible
    interface IFormattable
type DateTime = struct
    interface IConvertible
    interface IFormattable
    interface ISerializable
type DateTime = struct
    interface IConvertible
    interface ISpanFormattable
    interface IFormattable
    interface ISerializable
type DateTime = struct
    interface IConvertible
    interface ISpanFormattable
    interface IFormattable
    interface ISerializable
    interface IAdditionOperators<DateTime, TimeSpan, DateTime>
    interface IAdditiveIdentity<DateTime, TimeSpan>
    interface IComparisonOperators<DateTime, DateTime>
    interface IEqualityOperators<DateTime, DateTime>
    interface IMinMaxValue<DateTime>
    interface ISpanParseable<DateTime>
    interface IParseable<DateTime>
    interface ISubtractionOperators<DateTime, TimeSpan, DateTime>
    interface ISubtractionOperators<DateTime, DateTime, TimeSpan>
[<System.Serializable>]
type DateTime = struct
    interface IFormattable
    interface IConvertible
[<System.Serializable>]
type DateTime = struct
    interface IFormattable
    interface IConvertible
    interface ISerializable
type DateTime = struct
    interface IFormattable
Public Structure DateTime
Implements IComparable, IComparable(Of DateTime), IConvertible, IEquatable(Of DateTime), IFormattable
Public Structure DateTime
Implements IComparable, IComparable(Of DateTime), IConvertible, IEquatable(Of DateTime), IFormattable, ISerializable
Public Structure DateTime
Implements IComparable, IComparable(Of DateTime), IConvertible, IEquatable(Of DateTime), ISerializable, ISpanFormattable
Public Structure DateTime
Implements IAdditionOperators(Of DateTime, TimeSpan, DateTime), IAdditiveIdentity(Of DateTime, TimeSpan), IComparable(Of DateTime), IComparisonOperators(Of DateTime, DateTime), IConvertible, IEqualityOperators(Of DateTime, DateTime), IEquatable(Of DateTime), IMinMaxValue(Of DateTime), IParseable(Of DateTime), ISerializable, ISpanFormattable, ISpanParseable(Of DateTime), ISubtractionOperators(Of DateTime, DateTime, TimeSpan), ISubtractionOperators(Of DateTime, TimeSpan, DateTime)
Public Structure DateTime
Implements IComparable, IConvertible, IFormattable
Public Structure DateTime
Implements IComparable, IComparable(Of DateTime), IEquatable(Of DateTime), IFormattable
继承
DateTime
属性
实现

注解

重要

日本历法中的年号是根据天皇统治来命名的,因此预计会发生变化。 例如,2019 年 5 月 1 日在 JapaneseCalendarJapaneseLunisolarCalendar 中标志着令和年号的开始。 这种年号的变化会影响使用这些日历的所有应用程序。 有关详细信息以及如何确定应用程序是否受影响,请参阅在 .net 中的日式日历中处理新时代。 若要了解如何在 Windows 系统上测试应用程序以确保其应用程序更改的就绪性,请参阅准备应用程序以进行日本时代更改。 对于 .NET 中支持多个纪元的日历的功能,以及在处理支持多个纪元的日历时的最佳做法,请参阅使用 纪元

备注

本文中的一些 C# 示例运行在 Try.NET 内联代码运行程序和演练环境中。 选择“运行”按钮以在交互窗口中运行示例。 执行代码后,可通过再次选择“运行”来修改它并运行已修改的代码。 已修改的代码要么在交互窗口中运行,要么编译失败时,交互窗口将显示所有 C# 编译器错误消息。

Try.NET 内联代码运行程序和演练环境的本地时区是协调世界时 (UTC)。 这可能会影响用于说明 DateTimeDateTimeOffsetTimeZoneInfo 类型及其成员的示例的行为和输出。

本文包含几个使用类型 DateTime 的示例:

初始化示例

将对象格式设置为 DateTime 字符串

将字符串分析为 DateTime 对象

DateTime 分辨率

区域性和日历

持久性

本部分包含有关结构的许多常见用途 DateTime 的主题:

DateTime 类型表示日期和时间,值范围为 00:00:00 (午夜) ,0001 年 1 月 1 日安诺·多米尼 (公共时代) 到 11:59:59:59 上午 999 上午 31 点到上午 9999 年 12 月 31 日凌晨 11:59:59。 晚上 11:59:59。

时间值以 100 纳秒为单位测量,称为刻度线。 特定日期是自 1 月 1 日午夜 12:00 以来的时钟周期数,0001 A.D。 日历中 GregorianCalendar (C.E.) 。 该数字排除将按跃点秒添加的刻度线。 例如,刻度值为 31241376000000000L 表示星期五,1 月 01 日 0100 12:00:00 午夜。 值 DateTime 始终在显式或默认日历的上下文中表示。

备注

如果要使用要转换为其他时间间隔(例如分钟或秒)的刻度值,则应使用 TimeSpan.TicksPerDayTimeSpan.TicksPerHourTimeSpan.TicksPerMinuteTimeSpan.TicksPerSecondTimeSpan.TicksPerMillisecond 常量来执行转换。 例如,若要将指定数量的刻度 Second 表示的秒数添加到值的组件 DateTime ,可以使用表达式 dateValue.Second + nTicks/Timespan.TicksPerSecond

可以在 GitHub 上的 docs 存储库中查看本文中整个示例集的源Visual BasicF#C#

备注

使用特定时区中的日期和时间值的结构的替代方法是DateTimeDateTimeOffset结构。 该 DateTimeOffset 结构将日期和时间信息存储在专用 DateTime 字段中,以及该日期和时间与专用 Int16 字段中 UTC 不同的分钟数。 这使值能够 DateTimeOffset 反映特定时区中的时间,而 DateTime 值可以明确反映 UTC 和本地时区的时间。 有关使用日期和时间值时何时使用 DateTime 结构或 DateTimeOffset 结构的讨论,请参阅 “在 DateTime、DateTimeOffset、TimeSpan 和 TimeZoneInfo 之间选择”。

初始化 DateTime 对象

可以通过多种方式将初始值分配给新 DateTime 值:

  • 调用构造函数(指定值的参数)或使用隐式无参数构造函数。
  • DateTime 属性或方法的返回值赋值。
  • DateTime分析其字符串表示形式的值。
  • 使用特定于Visual Basic的语言功能实例化 a DateTime.

以下代码片段显示了每个代码片段的示例:

调用构造函数

调用构造函数的任何重载,这些重载 DateTime 指定日期和时间值的元素 ((例如年、月和日),或) 的刻度数。 以下代码使用 DateTime 指定年、月、日、小时、分钟和秒的构造函数创建特定日期。

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}"

需要DateTime初始化为其默认值时,DateTime调用结构的隐式无参数构造函数。 (有关值类型的隐式无参数构造函数的详细信息,请参阅 Value Types.) 某些编译器还支持声明值 DateTime 而不显式为其分配值。 在不显式初始化的情况下创建值也会导致默认值。 以下示例演示DateTime了 C# 和 Visual Basic 中的隐式无参数构造函数,以及DateTimeVisual 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}"
分配计算值

可以为对象分配 DateTime 属性或方法返回的日期和时间值。 以下示例将当前日期和时间、当前协调世界时 (UTC) 日期和时间以及当前日期分配给三个新 DateTime 变量。

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
分析表示 DateTime 的字符串

ParseParseExactTryParseTryParseExact方法均将字符串转换为其等效的日期和时间值。 以下示例使用 ParseParseExact 方法分析字符串并将其转换为 DateTime 值。 第二种格式使用 ISO 8601 标准支持的格式表示字符串格式的日期和时间。 此标准表示形式通常用于传输 Web 服务中的日期信息。

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)

TryParseTryParseExact方法指示字符串是否是值的有效表示形式DateTime,如果是,则执行转换。

Visual Basic特定于语言的语法

以下Visual Basic语句初始化新DateTime值。

Dim date1 As Date = #5/1/2008 8:30:52AM#

DateTime 值及其字符串表示形式

在内部,所有 DateTime 值都表示为 (自 10001 年 1 月 1 日午夜 12:00:00:00 以来经过的 100 纳秒) 间隔数的刻度数。 实际 DateTime 值与显示该值时显示的方式无关。 值的外观 DateTime 是格式设置操作的结果,该操作将值转换为其字符串表示形式。

日期和时间值的外观取决于区域性、国际标准、应用程序要求和个人偏好。 该 DateTime 结构通过重载 ToString为日期和时间值设置格式提供了灵活性。 默认 DateTime.ToString() 方法使用当前区域性的短日期和时间模式返回日期和时间值的字符串表示形式。 以下示例使用默认 DateTime.ToString() 方法。 它使用当前区域性的短日期和时间模式显示日期和时间。 en-US 区域性是运行该示例的计算机上的当前区域性。

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

可能需要在特定区域性中设置日期的格式,以支持服务器可能采用不同于客户端的区域性的 Web 方案。 使用 DateTime.ToString(IFormatProvider) 该方法指定区域性,以在特定区域性中创建短日期和时间表示形式。 以下示例使用此方法 DateTime.ToString(IFormatProvider) 使用 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

其他应用程序可能需要日期的不同字符串表示形式。 该方法 DateTime.ToString(String) 使用当前区域性的格式约定返回由标准或自定义格式说明符定义的字符串表示形式。 以下示例使用此方法 DateTime.ToString(String) 显示 en-US 区域性的完整日期和时间模式,即运行该示例的计算机上的当前区域性。

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

最后,可以使用该方法指定区域性和格式 DateTime.ToString(String, IFormatProvider) 。 以下示例使用该方法 DateTime.ToString(String, IFormatProvider) 显示 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

DateTime.ToString(String) 载还可用于自定义格式字符串来指定其他格式。 以下示例演示如何使用通常用于 Web 服务的 ISO 8601 标准格式设置字符串的格式。 Iso 8601 格式没有相应的标准格式字符串。

var date1 = new DateTime(2008, 3, 1, 7, 0, 0);
Console.WriteLine(date1.ToString("yyyyMMddTHH:mm:ssZ"));
// Displays 20080301T07:00:00Z
let date1 = DateTime(2008, 3, 1, 7, 0, 0)
printfn $"""{date1.ToString "yyyyMMddTHH:mm:ssZ"}"""
// Displays 20080301T07:00:00Z
Dim date1 As Date = #3/1/2008 7:00AM#
Console.WriteLine(date1.ToString("yyyyMMddTHH:mm:ssZ"))
' Displays 20080301T07:00:00Z

有关设置值格式 DateTime 的详细信息,请参阅 标准日期和时间格式字符串 以及 自定义日期和时间格式字符串

分析字符串中的 DateTime 值

分析将日期和时间的字符串表示形式转换为 DateTime 值。 通常,日期和时间字符串在应用程序中具有两种不同的用法:

  • 日期和时间采用多种形式,反映当前区域性或特定区域性的约定。 例如,应用程序允许当前区域性为 en-US 的用户输入日期值“12/15/2013”或“2013 年 12 月 15 日”。 它允许当前区域性为 en-gb 的用户输入日期值“15/12/2013”或“2013 年 12 月 15 日”。

  • 日期和时间以预定义格式表示。 例如,应用程序将日期序列化为“20130103”,而独立于运行应用的区域性。 应用程序可能需要以当前区域性的短日期格式输入日期。

可以使用 ParseTryParse 方法将区域性使用的常用日期和时间格式之一的字符串转换为 DateTime 值。 以下示例演示如何使用 TryParse 不同区域性特定格式的日期字符串转换为 DateTime 值。 它将当前文化更改为英国 (英国) ,并调用 GetDateTimeFormats() 该方法以生成日期和时间字符串数组。 然后,它将数组中的每个元素传递给 TryParse 该方法。 该示例的输出显示分析方法能够成功转换每个特定于区域性的日期和时间字符串。

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

可以使用 ParseExactTryParseExact 方法将必须与特定格式或格式匹配的字符串转换为 DateTime 值。 将一个或多个日期和时间格式字符串指定为分析方法的参数。 以下示例使用 TryParseExact(String, String[], IFormatProvider, DateTimeStyles, DateTime) 此方法将必须采用“yyyyMMdd”格式的字符串或“HHmmss”格式转换为 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

一个常见用途 ParseExact 是将字符串表示形式从 Web 服务转换,通常采用 ISO 8601 标准格式。 以下代码显示了要使用的正确格式字符串:

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}")

如果无法分析字符串,则 Parse 该方法会 ParseExact 引发异常。 和TryParseTryParseExact方法返回一个Boolean值,该值指示转换是成功还是失败。 在性能非常重要的情况下,应使用 TryParseTryParseExact 方法。 日期和时间字符串分析操作往往失败率较高,异常处理成本高昂。 如果用户输入字符串或来自未知源,请使用这些方法。

有关分析日期和时间值的详细信息,请参阅 分析日期和时间字符串

DateTime 值

类型中的 DateTime 时间值的说明通常使用协调世界时 (UTC) 标准表示。 协调世界时是格林威治时间 (格林尼治时间) 国际公认的名字。 协调世界时是以零度经度(UTC 原点)测量的时间。 夏令时不适用于 UTC。

本地时间相对于特定时区。 时区与时区偏移量相关联。 时区偏移量是从 UTC 原点测量的时区的偏移量(以小时为单位)。 此外,本地时间(可选)受夏令时的影响,这将增加或减去时间间隔调整。 通过将时区偏移量添加到 UTC 并在必要时调整夏令时来计算本地时间。 UTC 原点的时区偏移量为零。

UTC 时间适用于在文件中计算、比较和存储日期和时间。 本地时间适用于在桌面应用程序的用户界面中显示。 时区感知应用程序 (,例如许多 Web 应用程序) 也需要处理许多其他时区。

Kind如果对象的属性DateTimeDateTimeKind.Unspecified,则不指定表示的时间是本地时间、UTC 时间还是其他时区中的时间。

DateTime 解析

备注

作为对值执行日期和时间算术 DateTime 以度量已用时间的替代方法,可以使用该 Stopwatch 类。

Ticks 属性以秒 1,000 万分之一的单位表示日期和时间值。 该 Millisecond 属性返回日期和时间值的千分之一秒。 使用对属性的重复调用 DateTime.Now 来度量已用时间取决于系统时钟。 Windows 7 和 Windows 8 系统上的系统时钟分辨率约为 15 毫秒。 此分辨率影响小于 100 毫秒的小时间间隔。

以下示例演示了当前日期和时间值对系统时钟分辨率的依赖。 在此示例中,外部循环重复 20 次,内部循环用于延迟外部循环。 如果外部循环计数器的值为 10,则 Thread.Sleep 对该方法的调用将引入 5 毫秒延迟。 以下示例显示属性仅在调用Thread.Sleep后返回DateTime.Now.Milliseconds的毫秒数。

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

DateTime 操作

使用 DateTime 结构(例如 AddSubtract)的计算不会修改结构的值。 相反,计算返回一个新 DateTime 结构,其值是计算的结果。

时区之间的转换操作 (例如 UTC 和本地时间之间,或在一个时区和另一个时区之间,) 将夏令时考虑在内,但算术和比较运算不会考虑。

结构 DateTime 本身为从一个时区转换为另一个时区提供了有限的支持。 可以使用此方法 ToLocalTime 将 UTC 转换为本地时间,也可以使用 ToUniversalTime 该方法从本地时间转换为 UTC。 但是,类中 TimeZoneInfo 提供了一组完整的时区转换方法。 可以使用这些方法将任一世界时区中的时间转换为任何其他时区中的时间。

仅当对象表示同一时区中的时间时,对象的计算和比较 DateTime 才有意义。 可以使用对象 TimeZoneInfo 来表示值的时区,尽管两者 DateTime 是松散耦合的。 对象 DateTime 没有返回表示该日期和时间值的时区的对象的属性。 该 Kind 属性指示是否 DateTime 表示 UTC、本地时间或未指定。 在时区感知应用程序中,必须依赖一些外部机制来确定创建对象的时区 DateTime 。 可以使用一个结构来包装 DateTime 值和 TimeZoneInfo 表示 DateTime 值时区的对象。 有关在计算中使用 UTC 与值进行比较 DateTime 的详细信息,请参阅 使用日期和时间执行算术运算

每个 DateTime 成员隐式使用公历来执行其操作。 例外是隐式指定日历的方法。 其中包括指定日历的构造函数,以及具有派生自 IFormatProvider的参数的方法,例如 System.Globalization.DateTimeFormatInfo

类型成员 DateTime 的操作将考虑一些详细信息,例如跃点年数和一个月内的天数。

DateTime 值和日历

.NET Framework类库包括许多日历类,所有这些类都派生自Calendar该类。 它们是:

重要

日本历法中的年号是根据天皇统治来命名的,因此预计会发生变化。 例如,2019 年 5 月 1 日在 JapaneseCalendarJapaneseLunisolarCalendar 中标志着令和年号的开始。 这种年号的变化会影响使用这些日历的所有应用程序。 有关详细信息以及如何确定应用程序是否受影响,请参阅在 .net 中的日式日历中处理新时代。 若要了解如何在 Windows 系统上测试应用程序以确保其应用程序更改的就绪性,请参阅准备应用程序以进行日本时代更改。 对于 .NET 中支持多个纪元的日历的功能,以及在处理支持多个纪元的日历时的最佳做法,请参阅使用 纪元

每个区域性使用由其只读 CultureInfo.Calendar 属性定义的默认日历。 每个区域性都可能支持由其只读 CultureInfo.OptionalCalendars 属性定义的一个或多个日历。 当前由特定 CultureInfo 对象使用的日历由其 DateTimeFormatInfo.Calendar 属性定义。 它必须是数组中找到 CultureInfo.OptionalCalendars 的日历之一。

区域性的当前日历用于该区域性的所有格式设置操作。 例如,泰国佛教文化的默认日历是泰国佛教时代日历,该日历由该 ThaiBuddhistCalendar 类表示。 CultureInfo当表示泰国佛教文化的对象用于日期和时间格式设置操作时,默认使用泰国佛教时代日历。 仅当区域性 DateTimeFormatInfo.Calendar 的属性发生更改时,才使用公历,如以下示例所示:

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

区域性的当前日历也用于该区域性的所有分析操作中,如以下示例所示。

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

通过调用包含calendar参数的 DateTime 构造函数并向其Calendar传递表示该日历的对象来实例化一个DateTime值, (特定日历的年、月和日) 数。 以下示例使用日历中的 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 不包含 calendar 参数的构造函数假定日期和时间元素以公历中的单位表示。

所有其他 DateTime 属性和方法都使用公历。 例如,该 DateTime.Year 属性返回公历中的年份,该方法 DateTime.IsLeapYear(Int32) 假定 year 参数为公历中的年份。 使用公历的每个 DateTime 成员都有使用特定日历的 Calendar 类的对应成员。 例如,该方法 Calendar.GetYear 返回特定日历中的年份,该方法将 Calendar.IsLeapYear 参数解释 year 为特定日历中的年份编号。 以下示例使用 DateTime 类的 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

DateTime 结构包含一个 DayOfWeek 属性,该属性返回公历中的星期几。 它不包括允许检索年份周数的成员。 若要检索年份的一周,请调用单个日历 Calendar.GetWeekOfYear 的方法。 下面的示例进行了这方面的演示。

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

有关日期和日历的详细信息,请参阅 使用日历

保留 DateTime 值

可以通过四种方式保留 DateTime 值:

必须确保还原 DateTime 值的例程不会丢失数据或引发异常,而不考虑选择哪种技术。 DateTime 值应往返。 也就是说,原始值和还原的值应相同。 如果原始 DateTime 值表示单个时间瞬间,它应标识还原时相同的时间刻度。

将值保留为字符串

若要成功还原 DateTime 保留为字符串的值,请遵循以下规则:

DateTime 值保留为字符串时,最常见的错误是依赖于默认区域性或当前区域性的格式设置约定。 如果当前区域性在保存和还原字符串时不同,则会出现问题。 下面的示例演示了这些问题。 它使用当前区域性的格式设置约定保存五个日期,在本例中为英语 (美国) 。 它使用不同区域性的格式设置约定还原日期,在本例中为英国 (英国) 。 由于两种区域性的格式设置约定不同,因此无法还原两个日期,其余三个日期被错误解释。 此外,如果原始日期和时间值表示时间中的单个时刻,则还原时间不正确,因为时区信息丢失。

public static void PersistAsLocalStrings()
{
    SaveLocalDatesAsString();
    RestoreLocalDatesFromString();
}

private static void SaveLocalDatesAsString()
{
    DateTime[] dates = { new DateTime(2014, 6, 14, 6, 32, 0),
                   new DateTime(2014, 7, 10, 23, 49, 0),
                   new DateTime(2015, 1, 10, 1, 16, 0),
                   new DateTime(2014, 12, 20, 21, 45, 0),
                   new DateTime(2014, 6, 2, 15, 14, 0) };
    string output = null;

    Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}");
    Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:");
    for (int ctr = 0; ctr < dates.Length; ctr++)
    {
        Console.WriteLine(dates[ctr].ToString("f"));
        output += dates[ctr].ToString() + (ctr != dates.Length - 1 ? "|" : "");
    }
    var sw = new StreamWriter(filenameTxt);
    sw.Write(output);
    sw.Close();
    Console.WriteLine("Saved dates...");
}

private static void RestoreLocalDatesFromString()
{
    TimeZoneInfo.ClearCachedData();
    Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}");
    Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB");
    StreamReader sr = new StreamReader(filenameTxt);
    string[] inputValues = sr.ReadToEnd().Split(new char[] { '|' },
                                                StringSplitOptions.RemoveEmptyEntries);
    sr.Close();
    Console.WriteLine("The dates on an {0} system:",
                      Thread.CurrentThread.CurrentCulture.Name);
    foreach (var inputValue in inputValues)
    {
        DateTime dateValue;
        if (DateTime.TryParse(inputValue, out dateValue))
        {
            Console.WriteLine($"'{inputValue}' --> {dateValue:f}");
        }
        else
        {
            Console.WriteLine("Cannot parse '{inputValue}'");
        }
    }
    Console.WriteLine("Restored dates...");
}
// When saved on an en-US system, the example displays the following output:
//       Current Time Zone: (UTC-08:00) Pacific Time (US & Canada)
//       The dates on an en-US system:
//       Saturday, June 14, 2014 6:32 AM
//       Thursday, July 10, 2014 11:49 PM
//       Saturday, January 10, 2015 1:16 AM
//       Saturday, December 20, 2014 9:45 PM
//       Monday, June 02, 2014 3:14 PM
//       Saved dates...
//
// When restored on an en-GB system, the example displays the following output:
//       Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London
//       The dates on an en-GB system:
//       Cannot parse //6/14/2014 6:32:00 AM//
//       //7/10/2014 11:49:00 PM// --> 07 October 2014 23:49
//       //1/10/2015 1:16:00 AM// --> 01 October 2015 01:16
//       Cannot parse //12/20/2014 9:45:00 PM//
//       //6/2/2014 3:14:00 PM// --> 06 February 2014 15:14
//       Restored dates...
let saveLocalDatesAsString () =
    let dates = 
        [ DateTime(2014, 6, 14, 6, 32, 0)
          DateTime(2014, 7, 10, 23, 49, 0)
          DateTime(2015, 1, 10, 1, 16, 0)
          DateTime(2014, 12, 20, 21, 45, 0)
          DateTime(2014, 6, 2, 15, 14, 0) ]

    printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"
    printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"

    let output =
        [ for date in dates do
            printfn $"{date}"
            string date ]
        |> String.concat "|"

    use sw = new StreamWriter(filenameTxt)
    sw.Write output
    printfn "Saved dates..."

let restoreLocalDatesFromString () =
    TimeZoneInfo.ClearCachedData()
    printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"
    Thread.CurrentThread.CurrentCulture <- CultureInfo.CreateSpecificCulture "en-GB"

    use sr = new StreamReader(filenameTxt)
    let inputValues = 
        sr.ReadToEnd().Split('|', StringSplitOptions.RemoveEmptyEntries)

    printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"

    for inputValue in inputValues do
        match DateTime.TryParse inputValue with
        | true, dateValue ->
            printfn $"'{inputValue}' --> {dateValue:f}"
        | _ ->
            printfn $"Cannot parse '{inputValue}'"

    printfn "Restored dates..."

let persistAsLocalStrings () =
    saveLocalDatesAsString ()
    restoreLocalDatesFromString ()

// When saved on an en-US system, the example displays the following output:
//       Current Time Zone: (UTC-08:00) Pacific Time (US & Canada)
//       The dates on an en-US system:
//       Saturday, June 14, 2014 6:32 AM
//       Thursday, July 10, 2014 11:49 PM
//       Saturday, January 10, 2015 1:16 AM
//       Saturday, December 20, 2014 9:45 PM
//       Monday, June 02, 2014 3:14 PM
//       Saved dates...
//
// When restored on an en-GB system, the example displays the following output:
//       Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London
//       The dates on an en-GB system:
//       Cannot parse //6/14/2014 6:32:00 AM//
//       //7/10/2014 11:49:00 PM// --> 07 October 2014 23:49
//       //1/10/2015 1:16:00 AM// --> 01 October 2015 01:16
//       Cannot parse //12/20/2014 9:45:00 PM//
//       //6/2/2014 3:14:00 PM// --> 06 February 2014 15:14
//       Restored dates...
Public Sub PersistAsLocalStrings()
    SaveDatesAsStrings()
    RestoreDatesAsStrings()
End Sub

Private Sub SaveDatesAsStrings()
    Dim dates As Date() = {#6/14/2014 6:32AM#, #7/10/2014 11:49PM#,
                          #1/10/2015 1:16AM#, #12/20/2014 9:45PM#,
                          #6/2/2014 3:14PM#}
    Dim output As String = Nothing

    Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}")
    Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:")
    For ctr As Integer = 0 To dates.Length - 1
        Console.WriteLine(dates(ctr).ToString("f"))
        output += dates(ctr).ToString() + If(ctr <> dates.Length - 1, "|", "")
    Next
    Dim sw As New StreamWriter(filenameTxt)
    sw.Write(output)
    sw.Close()
    Console.WriteLine("Saved dates...")
End Sub

Private Sub RestoreDatesAsStrings()
    TimeZoneInfo.ClearCachedData()
    Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}")
    Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB")
    Dim sr As New StreamReader(filenameTxt)
    Dim inputValues As String() = sr.ReadToEnd().Split({"|"c}, StringSplitOptions.RemoveEmptyEntries)
    sr.Close()
    Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:")
    For Each inputValue In inputValues
        Dim dateValue As Date
        If DateTime.TryParse(inputValue, dateValue) Then
            Console.WriteLine($"'{inputValue}' --> {dateValue:f}")
        Else
            Console.WriteLine($"Cannot parse '{inputValue}'")
        End If
    Next
    Console.WriteLine("Restored dates...")
End Sub
' 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...

若要成功往返 DateTime 值,请执行以下步骤:

  1. 如果值表示单个时间刻,则通过调用 ToUniversalTime 该方法将其从本地时间转换为 UTC。
  2. 通过调用 ToString(String, IFormatProvider)String.Format(IFormatProvider, String, Object[]) 重载将日期转换为其字符串表示形式。 通过将固定区域性指定 CultureInfo.InvariantCulture 为参数,使用固定区域性的格式 provider 约定。 指定值应使用“O”或“R”标准格式字符串往返。

若要在不丢失数据丢失的情况下还原持久化 DateTime 值,请执行以下步骤:

  1. 通过调用 ParseExactTryParseExact 重载分析数据。 指定 CultureInfo.InvariantCultureprovider 参数,并使用在转换过程中用于 format 参数的标准格式字符串。 在 DateTimeStyles.RoundtripKind 参数中包含 styles 值。
  2. DateTime如果值表示时间中的单个时刻,请调用ToLocalTime该方法,将分析日期从 UTC 转换为本地时间。

以下示例使用固定区域性和“O”标准格式字符串来确保 DateTime 保存和还原的值表示同一时刻,而不考虑源和目标系统的系统、区域性或时区。

public static void PersistAsInvariantStrings()
{
    SaveDatesAsInvariantStrings();
    RestoreDatesAsInvariantStrings();
}

private static void SaveDatesAsInvariantStrings()
{
    DateTime[] dates = { new DateTime(2014, 6, 14, 6, 32, 0),
                   new DateTime(2014, 7, 10, 23, 49, 0),
                   new DateTime(2015, 1, 10, 1, 16, 0),
                   new DateTime(2014, 12, 20, 21, 45, 0),
                   new DateTime(2014, 6, 2, 15, 14, 0) };
    string output = null;

    Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}");
    Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:");
    for (int ctr = 0; ctr < dates.Length; ctr++)
    {
        Console.WriteLine(dates[ctr].ToString("f"));
        output += dates[ctr].ToUniversalTime().ToString("O", CultureInfo.InvariantCulture)
                  + (ctr != dates.Length - 1 ? "|" : "");
    }
    var sw = new StreamWriter(filenameTxt);
    sw.Write(output);
    sw.Close();
    Console.WriteLine("Saved dates...");
}

private static void RestoreDatesAsInvariantStrings()
{
    TimeZoneInfo.ClearCachedData();
    Console.WriteLine("Current Time Zone: {0}",
                      TimeZoneInfo.Local.DisplayName);
    Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB");
    StreamReader sr = new StreamReader(filenameTxt);
    string[] inputValues = sr.ReadToEnd().Split(new char[] { '|' },
                                                StringSplitOptions.RemoveEmptyEntries);
    sr.Close();
    Console.WriteLine("The dates on an {0} system:",
                      Thread.CurrentThread.CurrentCulture.Name);
    foreach (var inputValue in inputValues)
    {
        DateTime dateValue;
        if (DateTime.TryParseExact(inputValue, "O", CultureInfo.InvariantCulture,
                              DateTimeStyles.RoundtripKind, out dateValue))
        {
            Console.WriteLine($"'{inputValue}' --> {dateValue.ToLocalTime():f}");
        }
        else
        {
            Console.WriteLine("Cannot parse '{0}'", inputValue);
        }
    }
    Console.WriteLine("Restored dates...");
}
// When saved on an en-US system, the example displays the following output:
//       Current Time Zone: (UTC-08:00) Pacific Time (US & Canada)
//       The dates on an en-US system:
//       Saturday, June 14, 2014 6:32 AM
//       Thursday, July 10, 2014 11:49 PM
//       Saturday, January 10, 2015 1:16 AM
//       Saturday, December 20, 2014 9:45 PM
//       Monday, June 02, 2014 3:14 PM
//       Saved dates...
//
// When restored on an en-GB system, the example displays the following output:
//       Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London
//       The dates on an en-GB system:
//       '2014-06-14T13:32:00.0000000Z' --> 14 June 2014 14:32
//       '2014-07-11T06:49:00.0000000Z' --> 11 July 2014 07:49
//       '2015-01-10T09:16:00.0000000Z' --> 10 January 2015 09:16
//       '2014-12-21T05:45:00.0000000Z' --> 21 December 2014 05:45
//       '2014-06-02T22:14:00.0000000Z' --> 02 June 2014 23:14
//       Restored dates...
let saveDatesAsInvariantStrings () =
    let dates = 
        [ DateTime(2014, 6, 14, 6, 32, 0)
          DateTime(2014, 7, 10, 23, 49, 0)
          DateTime(2015, 1, 10, 1, 16, 0)
          DateTime(2014, 12, 20, 21, 45, 0)
          DateTime(2014, 6, 2, 15, 14, 0) ]

    printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"
    printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"

    let output =
        [ for date in dates do
            printfn $"{date:f}"
            date.ToUniversalTime().ToString("O", CultureInfo.InvariantCulture) ]
        |> String.concat "|"

    use sw = new StreamWriter(filenameTxt)
    sw.Write output
    printfn "Saved dates..."

let restoreDatesAsInvariantStrings () =
    TimeZoneInfo.ClearCachedData()
    printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"
    Thread.CurrentThread.CurrentCulture <- CultureInfo.CreateSpecificCulture "en-GB"
    
    use sr = new StreamReader(filenameTxt)
    let inputValues = 
        sr.ReadToEnd().Split('|', StringSplitOptions.RemoveEmptyEntries)

    printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"

    for inputValue in inputValues do
        match DateTime.TryParseExact(inputValue, "O", CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind) with
        | true, dateValue ->
            printfn $"'{inputValue}' --> {dateValue.ToLocalTime():f}"
        | _ ->
            printfn $"Cannot parse '{inputValue}'"

    printfn "Restored dates..."

let persistAsInvariantStrings () =
    saveDatesAsInvariantStrings ()
    restoreDatesAsInvariantStrings ()

// When saved on an en-US system, the example displays the following output:
//       Current Time Zone: (UTC-08:00) Pacific Time (US & Canada)
//       The dates on an en-US system:
//       Saturday, June 14, 2014 6:32 AM
//       Thursday, July 10, 2014 11:49 PM
//       Saturday, January 10, 2015 1:16 AM
//       Saturday, December 20, 2014 9:45 PM
//       Monday, June 02, 2014 3:14 PM
//       Saved dates...
//
// When restored on an en-GB system, the example displays the following output:
//       Current Time Zone: (UTC) Dublin, Edinburgh, Lisbon, London
//       The dates on an en-GB system:
//       '2014-06-14T13:32:00.0000000Z' --> 14 June 2014 14:32
//       '2014-07-11T06:49:00.0000000Z' --> 11 July 2014 07:49
//       '2015-01-10T09:16:00.0000000Z' --> 10 January 2015 09:16
//       '2014-12-21T05:45:00.0000000Z' --> 21 December 2014 05:45
//       '2014-06-02T22:14:00.0000000Z' --> 02 June 2014 23:14
//       Restored dates...
Public Sub PersistAsInvariantStrings()
    SaveDatesAsInvariantStrings()
    RestoreDatesAsInvariantStrings()
End Sub

Private Sub SaveDatesAsInvariantStrings()
    Dim dates As Date() = {#6/14/2014 6:32AM#, #7/10/2014 11:49PM#,
                          #1/10/2015 1:16AM#, #12/20/2014 9:45PM#,
                          #6/2/2014 3:14PM#}
    Dim output As String = Nothing

    Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}")
    Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:")
    For ctr As Integer = 0 To dates.Length - 1
        Console.WriteLine(dates(ctr).ToString("f"))
        output += dates(ctr).ToUniversalTime().ToString("O", CultureInfo.InvariantCulture) +
                                   If(ctr <> dates.Length - 1, "|", "")
    Next
    Dim sw As New StreamWriter(filenameTxt)
    sw.Write(output)
    sw.Close()
    Console.WriteLine("Saved dates...")
End Sub

Private Sub RestoreDatesAsInvariantStrings()
    TimeZoneInfo.ClearCachedData()
    Console.WriteLine("Current Time Zone: {0}",
                    TimeZoneInfo.Local.DisplayName)
    Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB")
    Dim sr As New StreamReader(filenameTxt)
    Dim inputValues As String() = sr.ReadToEnd().Split({"|"c}, StringSplitOptions.RemoveEmptyEntries)
    sr.Close()
    Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:")
    For Each inputValue In inputValues
        Dim dateValue As Date
        If DateTime.TryParseExact(inputValue, "O", CultureInfo.InvariantCulture,
                          DateTimeStyles.RoundtripKind, dateValue) Then
            Console.WriteLine($"'{inputValue}' --> {dateValue.ToLocalTime():f}")
        Else
            Console.WriteLine($"Cannot parse '{inputValue}'")
        End If
    Next
    Console.WriteLine("Restored dates...")
End Sub
' 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...
将值保留为整数

可以将日期和时间保留为 Int64 表示多个刻度线的值。 在这种情况下,无需考虑保留值并还原到的系统 DateTime 区域性。

将值保留 DateTime 为整数:

若要还原 DateTime 已保留为整数的值:

  1. 通过将值DateTime(Int64)传递给Int64构造函数来实例化新DateTime对象。
  2. DateTime如果值表示时间中的单个时刻,则通过调用ToLocalTime该方法将其从 UTC 转换为本地时间。

以下示例将值数组 DateTime 保留为美国太平洋时区系统中的整数。 它在 UTC 区域中的系统上还原它。 包含整数的文件包含一个 Int32 值,该值指示紧随其后的值的总数 Int64

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...
Public Sub PersistAsIntegers()
    SaveDatesAsIntegers()
    RestoreDatesAsIntegers()
End Sub

Private Sub SaveDatesAsIntegers()
    Dim dates As Date() = {#6/14/2014 6:32AM#, #7/10/2014 11:49PM#,
                          #1/10/2015 1:16AM#, #12/20/2014 9:45PM#,
                          #6/2/2014 3:14PM#}

    Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}")
    Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:")
    Dim ticks(dates.Length - 1) As Long
    For ctr As Integer = 0 To dates.Length - 1
        Console.WriteLine(dates(ctr).ToString("f"))
        ticks(ctr) = dates(ctr).ToUniversalTime().Ticks
    Next
    Dim fs As New FileStream(filenameInts, FileMode.Create)
    Dim bw As New BinaryWriter(fs)
    bw.Write(ticks.Length)
    For Each tick In ticks
        bw.Write(tick)
    Next
    bw.Close()
    Console.WriteLine("Saved dates...")
End Sub

Private Sub RestoreDatesAsIntegers()
    TimeZoneInfo.ClearCachedData()
    Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}")
    Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB")
    Dim fs As New FileStream(filenameInts, FileMode.Open)
    Dim br As New BinaryReader(fs)
    Dim items As Integer
    Dim dates As DateTime()

    Try
        items = br.ReadInt32()
        ReDim dates(items - 1)

        For ctr As Integer = 0 To items - 1
            Dim ticks As Long = br.ReadInt64()
            dates(ctr) = New DateTime(ticks).ToLocalTime()
        Next
    Catch e As EndOfStreamException
        Console.WriteLine("File corruption detected. Unable to restore data...")
        Exit Sub
    Catch e As IOException
        Console.WriteLine("Unspecified I/O error. Unable to restore data...")
        Exit Sub
    Catch e As OutOfMemoryException     'Thrown in array initialization.
        Console.WriteLine("File corruption detected. Unable to restore data...")
        Exit Sub
    Finally
        br.Close()
    End Try

    Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:")
    For Each value In dates
        Console.WriteLine(value.ToString("f"))
    Next
    Console.WriteLine("Restored dates...")
End Sub
' 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...

序列化 DateTime 值

可以通过序列化将值保存到 DateTime 流或文件,然后通过反序列化还原它们。 DateTime 数据以一些指定的对象格式序列化。 反序列化对象时会还原这些对象。 格式化程序或序列化程序(如 XmlSerializerBinaryFormatter)处理序列化和反序列化的过程。 有关序列化和.NET Framework支持的序列化类型的详细信息,请参阅序列化

以下示例使用 XmlSerializer 类对值进行序列化和反序列化 DateTime 。 这些值表示二十一世纪的所有跃年天数。 如果示例在当前区域性为英国 (英国) 的系统上运行,则输出表示结果。 由于已反序列化 DateTime 对象本身,因此代码不必处理日期和时间格式的文化差异。

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;
    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
Public Sub PersistAsXml()
    ' Serialize the data.
    Dim leapYears As New List(Of DateTime)()
    For year As Integer = 2000 To 2100 Step 4
        If Date.IsLeapYear(year) Then
            leapYears.Add(New Date(year, 2, 29))
        End If
    Next
    Dim dateArray As DateTime() = leapYears.ToArray()

    Dim serializer As New XmlSerializer(dateArray.GetType())
    Dim sw As TextWriter = New StreamWriter(filenameXml)

    Try
        serializer.Serialize(sw, dateArray)
    Catch e As InvalidOperationException
        Console.WriteLine(e.InnerException.Message)
    Finally
        If sw IsNot Nothing Then sw.Close()
    End Try

    ' Deserialize the data.
    Dim deserializedDates As Date()
    Using fs As New FileStream(filenameXml, FileMode.Open)
        deserializedDates = CType(serializer.Deserialize(fs), Date())
    End Using

    ' Display the dates.
    Console.WriteLine($"Leap year days from 2000-2100 on an {Thread.CurrentThread.CurrentCulture.Name} system:")
    Dim nItems As Integer
    For Each dat In deserializedDates
        Console.Write($"   {dat:d}     ")
        nItems += 1
        If nItems Mod 5 = 0 Then Console.WriteLine()
    Next
End Sub
' 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

上一个示例不包括时间信息。 如果某个 DateTime 值表示某个时间的时刻,并且表示为本地时间,则先将其从本地时间转换为 UTC,然后通过调用 ToUniversalTime 该方法对其进行序列化。 反序列化后,通过调用 ToLocalTime 该方法将其从 UTC 转换为本地时间。 以下示例使用 BinaryFormatter 该类对位于美国太平洋标准时区的系统上的数据进行序列化 DateTime ,并在美国中部标准区域中的系统上反序列化数据。

public static void PersistBinary()
{
    SaveDatesBinary();
    RestoreDatesBinary();
}

private static void SaveDatesBinary()
{
    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) };
    var fs = new FileStream(filenameBin, FileMode.Create);
    var bin = new BinaryFormatter();

    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"));
        dates[ctr] = dates[ctr].ToUniversalTime();
    }
    bin.Serialize(fs, dates);
    fs.Close();
    Console.WriteLine("Saved dates...");
}

private static void RestoreDatesBinary()
{
    TimeZoneInfo.ClearCachedData();
    Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}");
    Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB");

    FileStream fs = new FileStream(filenameBin, FileMode.Open);
    BinaryFormatter bin = new BinaryFormatter();
    var dates = (DateTime[])bin.Deserialize(fs);
    fs.Close();

    Console.WriteLine($"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:");
    foreach (var value in dates)
        Console.WriteLine(value.ToLocalTime().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-6:00) Central Time (US & Canada)
//       The dates on an en-GB system:
//       14 June 2014 08:32
//       11 July 2014 01:49
//       10 January 2015 03:16
//       20 December 2014 23:45
//       02 June 2014 17:14
//       Restored dates...
// BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.

let saveDatesBinary () =
    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) |]
        |> Array.map (fun date -> 
            printfn $"{date:f}"
            date.ToUniversalTime() )

    use fs = new FileStream(filenameBin, FileMode.Create)
    let bin = BinaryFormatter()

    printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"
    printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"
    
    bin.Serialize(fs, dates)
    printfn "Saved dates..."

let restoreDatesBinary () =
    TimeZoneInfo.ClearCachedData()
    printfn $"Current Time Zone: {TimeZoneInfo.Local.DisplayName}"
    Thread.CurrentThread.CurrentCulture <- CultureInfo.CreateSpecificCulture "en-GB"

    use fs = new FileStream(filenameBin, FileMode.Open)
    let bin = BinaryFormatter()
    let dates = bin.Deserialize fs :?> DateTime []

    printfn $"The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:"
    for value in dates do
        printfn $"{value.ToLocalTime():f}"

    printfn "Restored dates..."

let persistBinary () =
    saveDatesBinary ()
    restoreDatesBinary ()

// 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-6:00) Central Time (US & Canada)
//       The dates on an en-GB system:
//       14 June 2014 08:32
//       11 July 2014 01:49
//       10 January 2015 03:16
//       20 December 2014 23:45
//       02 June 2014 17:14
//       Restored dates...
Public Sub PersistBinary()
    SaveDatesBinary()
    RestoreDatesBinary()
End Sub

Private Sub SaveDatesBinary()
    Dim dates As Date() = {#6/14/2014 6:32AM#, #7/10/2014 11:49PM#,
                          #1/10/2015 1:16AM#, #12/20/2014 9:45PM#,
                          #6/2/2014 3:14PM#}
    Dim fs As New FileStream(filenameBin, FileMode.Create)
    Dim bin As New BinaryFormatter()

    Console.WriteLine($"Current Time Zone: {TimeZoneInfo.Local.DisplayName}")
    Console.WriteLine("The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:")
    For ctr As Integer = 0 To dates.Length - 1
        Console.WriteLine(dates(ctr).ToString("f"))
        dates(ctr) = dates(ctr).ToUniversalTime()
    Next
    bin.Serialize(fs, dates)
    fs.Close()
    Console.WriteLine("Saved dates...")
End Sub

Private Sub RestoreDatesBinary()
    TimeZoneInfo.ClearCachedData()
    Console.WriteLine("Current Time Zone: {TimeZoneInfo.Local.DisplayName}")
    Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB")

    Dim fs As New FileStream(filenameBin, FileMode.Open)
    Dim bin As New BinaryFormatter()
    Dim dates As DateTime() = DirectCast(bin.Deserialize(fs), Date())
    fs.Close()

    Console.WriteLine("The dates on an {Thread.CurrentThread.CurrentCulture.Name} system:")
    For Each value In dates
        Console.WriteLine(value.ToLocalTime().ToString("f"))
    Next
    Console.WriteLine("Restored dates...")
End Sub
' 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-6:00) Central Time (US & Canada)
'       The dates on an en-GB system:
'       14 June 2014 08:32
'       11 July 2014 01:49
'       10 January 2015 03:16
'       20 December 2014 11:45
'       02 June 2014 17:14
'       Restored dates...

序列化 DateTime 和时区数据

前面的示例都假定 DateTime 值以本地时间表示。 代码转换了 UTC 和本地时间之间的值,以便它们反映源系统和目标系统上的相同时间刻度。 DateTime 值还可能反映时区中除本地和 UTC 以外的时间刻度。 由于结构不是时区感知的 DateTime ,因此必须同时序列化 DateTime 表示其时区的值和 TimeZoneInfo 对象。 创建一个类型,其字段包括 DateTime 值及其时区。 以下示例定义一个 DateWithTimeZone 结构。

using System;

namespace DateTimeExtensions
{
    [Serializable]
    public struct DateWithTimeZone
    {
        private TimeZoneInfo tz;
        private DateTime dt;

        public DateWithTimeZone(DateTime dateValue, TimeZoneInfo timeZone)
        {
            dt = dateValue;
            tz = timeZone ?? TimeZoneInfo.Local;
        }

        public TimeZoneInfo TimeZone
        {
            get { return (tz); }
            set { tz = value; }
        }

        public DateTime DateTime
        {
            get { return (dt); }
            set { dt = value; }
        }
    }
}
namespace DateTimeExtensions

open System

[<Serializable>]
type DateWithTimeZone =
    struct
        val TimeZone: TimeZoneInfo
        val DateTime: DateTime
        new (dateValue, timeZone) = 
            { DateTime = dateValue; 
              TimeZone = 
                if isNull timeZone then TimeZoneInfo.Local
                else timeZone }
    end
Namespace DateTimeExtensions
    <Serializable> Public Structure DateWithTimeZone
        Private tz As TimeZoneInfo
        Private dt As DateTime

        Public Sub New(dateValue As DateTime, timeZone As TimeZoneInfo)
            dt = dateValue
            tz = If(timeZone, TimeZoneInfo.Local)
        End Sub

        Public Property TimeZone As TimeZoneInfo
            Get
                Return tz
            End Get
            Set
                tz = Value
            End Set
        End Property

        Public Property DateTime As Date
            Get
                Return dt
            End Get
            Set
                dt = Value
            End Set
        End Property
    End Structure
End Namespace

重要

结构 DateWithTimeZone 在下两个示例中使用,这些示例对对象数组 DateWithTimeZone 进行序列化和反序列化。 可以在 GitHub 上的 docs 存储库中查看本文中Visual Basic、F#C# 中整个示例集的源。

然后,通过使用 DateWithTimeZone 结构,可以保留日期和时间以及时区信息。 以下示例使用 BinaryFormatter 类序列化对象数组 DateWithTimeZone

public static void SaveDateWithTimeZone()
{
    DateWithTimeZone[] dates = { new DateWithTimeZone(new DateTime(2014, 8, 9, 19, 30, 0),
                              TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time")),
                          new DateWithTimeZone(new DateTime(2014, 8, 15, 19, 0, 0),
                              TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time")),
                          new DateWithTimeZone(new DateTime(2014, 8, 22, 19, 30, 0),
                              TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time")),
                          new DateWithTimeZone(new DateTime(2014, 8, 28, 19, 0, 0),
                              TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time")) };
    var fs = new FileStream(@".\Schedule.bin", FileMode.Create);
    var formatter = new BinaryFormatter();
    try
    {
        formatter.Serialize(fs, dates);
        // Display dates.
        foreach (var date in dates)
        {
            TimeZoneInfo tz = date.TimeZone;
            Console.WriteLine($"{date.DateTime} {(tz.IsDaylightSavingTime(date.DateTime) ? tz.DaylightName : tz.StandardName)}");
        }
    }
    catch (SerializationException e)
    {
        Console.WriteLine($"Serialization failed. Reason: {e.Message}");
    }
    finally
    {
        if (fs != null) fs.Close();
    }
}
// The example displays the following output:
//       8/9/2014 7:30:00 PM Eastern Daylight Time
//       8/15/2014 7:00:00 PM Pacific Daylight Time
//       8/22/2014 7:30:00 PM Eastern Daylight Time
//       8/28/2014 7:00:00 PM Eastern Daylight Time
// BinaryFormatter serialization is obsolete and should not be used. See https://aka.ms/binaryformatter for more information.

let saveDateWithTimeZone () =
    let dates = 
        [| DateWithTimeZone(DateTime(2014, 8, 9, 19, 30, 0),
                                TimeZoneInfo.FindSystemTimeZoneById "Eastern Standard Time")
           DateWithTimeZone(DateTime(2014, 8, 15, 19, 0, 0),
                                TimeZoneInfo.FindSystemTimeZoneById "Pacific Standard Time")
           DateWithTimeZone(DateTime(2014, 8, 22, 19, 30, 0),
                                TimeZoneInfo.FindSystemTimeZoneById "Eastern Standard Time")
           DateWithTimeZone(DateTime(2014, 8, 28, 19, 0, 0),
                                TimeZoneInfo.FindSystemTimeZoneById "Eastern Standard Time") |]

    use fs = new FileStream(@".\Schedule.bin", FileMode.Create)
    let formatter = BinaryFormatter()
    try
        formatter.Serialize(fs, dates)
        // Display dates.
        for date in dates do
            let tz = date.TimeZone
            printfn $"{date.DateTime} {if tz.IsDaylightSavingTime date.DateTime then tz.DaylightName else tz.StandardName}"
    with :? SerializationException as e ->
        printfn $"Serialization failed. Reason: {e.Message}"

// The example displays the following output:
//       8/9/2014 7:30:00 PM Eastern Daylight Time
//       8/15/2014 7:00:00 PM Pacific Daylight Time
//       8/22/2014 7:30:00 PM Eastern Daylight Time
//       8/28/2014 7:00:00 PM Eastern Daylight Time
Public Sub SaveDateWithTimeZone()
    Dim dates As DateWithTimeZone() = {New DateWithTimeZone(#8/9/2014 7:30PM#,
                                      TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time")),
                                  New DateWithTimeZone(#8/15/2014 7:00PM#,
                                      TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time")),
                                  New DateWithTimeZone(#8/22/2014 7:30PM#,
                                      TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time")),
                                  New DateWithTimeZone(#8/28/2014 7:00PM#,
                                      TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"))}
    Dim fs As New FileStream(".\Schedule.bin", FileMode.Create)
    Dim formatter As New BinaryFormatter()
    Try
        formatter.Serialize(fs, dates)
    Catch e As SerializationException
        Console.WriteLine($"Serialization failed. Reason: {e.Message}")
    Finally
        If fs IsNot Nothing Then fs.Close()
    End Try
    ' Display dates.
    For Each dateInfo In dates
        Dim tz As TimeZoneInfo = dateInfo.TimeZone
        Console.WriteLine($"{dateInfo.DateTime} {If(tz.IsDaylightSavingTime(dateInfo.DateTime), tz.DaylightName, tz.StandardName)}")
    Next
End Sub
' The example displays the following output:
'       8/9/2014 7:30:00 PM Eastern Daylight Time
'       8/15/2014 7:00:00 PM Pacific Daylight Time
'       8/22/2014 7:30:00 PM Eastern Daylight Time
'       8/28/2014 7:00:00 PM Eastern Daylight Time

然后,以下示例调用 BinaryFormatter.Deserialize 该方法以反序列化它。

public static void RestoreDateWithTimeZone()
{
    const string filename = @".\Schedule.bin";
    FileStream fs;
    if (File.Exists(filename))
    {
        fs = new FileStream(filename, FileMode.Open);
    }
    else
    {
        Console.WriteLine("Unable to find file to deserialize.");
        return;
    }

    var formatter = new BinaryFormatter();
    DateWithTimeZone[] dates;
    try
    {
        dates = (DateWithTimeZone[])formatter.Deserialize(fs);
        // Display dates.
        foreach (var date in dates)
        {
            TimeZoneInfo tz = date.TimeZone;
            Console.WriteLine($"{ date.DateTime} {(tz.IsDaylightSavingTime(date.DateTime) ? tz.DaylightName : tz.StandardName)}");
        }
    }
    catch (SerializationException e)
    {
        Console.WriteLine($"Deserialization failed. Reason: {e.Message}");
    }
    finally
    {
        if (fs != null) fs.Close();
    }
}
// The example displays the following output:
//       8/9/2014 7:30:00 PM Eastern Daylight Time
//       8/15/2014 7:00:00 PM Pacific Daylight Time
//       8/22/2014 7:30:00 PM Eastern Daylight Time
//       8/28/2014 7:00:00 PM Eastern Daylight Time
let restoreDateWithTimeZone () =
    let filename = @".\Schedule.bin"
    if File.Exists filename then
        use fs = new FileStream(filename, FileMode.Open)

        let formatter = BinaryFormatter()
        try
            let dates = formatter.Deserialize fs :?> DateWithTimeZone []
            // Display dates.
            for date in dates do
                let tz = date.TimeZone
                printfn $"{date.DateTime} {if tz.IsDaylightSavingTime date.DateTime then tz.DaylightName else tz.StandardName}"
        with :? SerializationException as e ->
            printfn $"Deserialization failed. Reason: {e.Message}"
    else
        printfn "Unable to find file to deserialize."

// The example displays the following output:
//       8/9/2014 7:30:00 PM Eastern Daylight Time
//       8/15/2014 7:00:00 PM Pacific Daylight Time
//       8/22/2014 7:30:00 PM Eastern Daylight Time
//       8/28/2014 7:00:00 PM Eastern Daylight Time
Public Sub RestoreDateWithTimeZone()
    Dim fs As FileStream
    If File.Exists(filename) Then
        fs = New FileStream(filename, FileMode.Open)
    Else
        Console.WriteLine("Unable to find file to deserialize.")
        Exit Sub
    End If

    Dim formatter As New BinaryFormatter()
    Dim dates As DateWithTimeZone ()= Nothing
    Try
        dates = DirectCast(formatter.Deserialize(fs), DateWithTimeZone())
        ' Display dates.
        For Each dateInfo In dates
            Dim tz As TimeZoneInfo = dateInfo.TimeZone
            Console.WriteLine($"{dateInfo.DateTime} {If(tz.IsDaylightSavingTime(dateInfo.DateTime), tz.DaylightName, tz.StandardName)}")
        Next
    Catch e As SerializationException
        Console.WriteLine("Deserialization failed. Reason: {e.Message}")
    Finally
        If fs IsNot Nothing Then fs.Close()
    End Try
End Sub
' The example displays the following output:
'       8/9/2014 7:30:00 PM Eastern Daylight Time
'       8/15/2014 7:00:00 PM Pacific Daylight Time
'       8/22/2014 7:30:00 PM Eastern Daylight Time
'       8/28/2014 7:00:00 PM Eastern Daylight Time

DateTime 与 TimeSpan

TimeSpanDateTime类型因表示DateTime时间的瞬间而TimeSpan表示时间间隔不同。 你可以从另一个实例中减去一个TimeSpan实例DateTime,以获取表示它们之间的时间间隔的对象。 或者,可以向当前DateTime添加正TimeSpan值以获取DateTime表示未来日期的值。

可以从对象中添加或减去时间间隔 DateTime 。 时间间隔可以是负的或正的,并且可以以刻度、秒或对象等 TimeSpan 单位表示。

比较容差内的相等性

值的 DateTime 相等比较精确。 这意味着两个值必须表示为相同数量的刻度,才能被视为相等。 对于许多应用程序来说,这种精度通常是不必要的,甚至不正确。 通常,需要测试对象是否DateTime大致相等

以下示例演示如何比较大致等效 DateTime 的值。 声明它们相等时,它接受一小部分差异。

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

COM 互操作注意事项

DateTime据说,将传输到 COM 应用程序的值,然后传输回托管应用程序。 但是,仅 DateTime 指定一个时间的值不会按预期往返。

如果你只往返时间(如下午 3 点),最后日期和时间是 1899 年 12 月 30 日 C.E. 下午3:00,而不是1月,1,0001 C.E. 下午3:00 .NET Framework和 COM 假定仅指定一个时间时的默认日期。 但是,COM 系统假定基准日期为 1899 C.E.12 月 30 日,而.NET Framework假定 1 月 1 日 C.E.

当仅将时间从.NET Framework传递到 COM 时,将执行特殊处理,以便将时间转换为 COM 使用的格式。 如果仅将一个时间从 COM 传递到.NET Framework,则不会执行任何特殊处理,因为该时间会在 1899 年 12 月 30 日或 1899 年 12 月 30 日之前损坏合法日期和时间。 如果某个日期从 COM 开始往返,则.NET Framework和 COM 将保留日期。

.NET Framework和 COM 的行为意味着,如果应用程序往返仅DateTime指定时间,则应用程序必须记住修改或忽略最终DateTime对象中的错误日期。

构造函数

DateTime(Int32, Int32, Int32)

DateTime 结构的新实例初始化为指定的年、月和日。

DateTime(Int32, Int32, Int32, Calendar)

DateTime 结构的新实例初始化为指定日历的指定年、月和日。

DateTime(Int32, Int32, Int32, Int32, Int32, Int32)

DateTime 结构的新实例初始化为指定的年、月、日、小时、分钟和秒。

DateTime(Int32, Int32, Int32, Int32, Int32, Int32, Calendar)

DateTime 结构的新实例初始化为指定日历的年、月、日、小时、分钟和秒。

DateTime(Int32, Int32, Int32, Int32, Int32, Int32, DateTimeKind)

DateTime 结构的新实例初始化为指定年、月、日、小时、分钟、秒和协调世界时 (UTC) 或本地时间。

DateTime(Int32, Int32, Int32, Int32, Int32, Int32, Int32)

DateTime 结构的新实例初始化为指定的年、月、日、小时、分钟、秒和毫秒。

DateTime(Int32, Int32, Int32, Int32, Int32, Int32, Int32, Calendar)

DateTime 结构的新实例初始化为指定日历的指定年、月、日、小时、分钟、秒和毫秒。

DateTime(Int32, Int32, Int32, Int32, Int32, Int32, Int32, Calendar, DateTimeKind)

DateTime 结构的新实例初始化为指定日历的指定年、月、日、小时、分钟、秒、毫秒和协调世界时 (UTC) 或本地时间。

DateTime(Int32, Int32, Int32, Int32, Int32, Int32, Int32, DateTimeKind)

DateTime 结构的新实例初始化为指定年、月、日、小时、分钟、秒、毫秒和协调世界时 (UTC) 或本地时间。

DateTime(Int64)

DateTime 结构的新实例初始化为指定的刻度数。

DateTime(Int64, DateTimeKind)

DateTime 结构的新实例初始化为指定的计时周期数以及协调世界时 (UTC) 或本地时间。

字段

MaxValue

表示 DateTime 的最大可能值。 此字段为只读。

MinValue

表示 DateTime 的最小可能值。 此字段为只读。

UnixEpoch

此常量的值等效于公历 1970 年 1 月 1 日的 00:00:00.0000000 UTC。 UnixEpoch 定义 Unix 时间等于 0 的时间点。

属性

Date

获取此实例的日期部分。

Day

获取此实例所表示的日期为该月中的第几天。

DayOfWeek

获取此实例所表示的日期是星期几。

DayOfYear

获取此实例所表示的日期是该年中的第几天。

Hour

获取此实例所表示日期的小时部分。

Kind

获取一个值,该值指示由此实例表示的时间是基于本地时间、协调世界时 (UTC),还是两者皆否。

Millisecond

获取此实例所表示日期的毫秒部分。

Minute

获取此实例所表示日期的分钟部分。

Month

获取此实例所表示日期的月份部分。

Now

获取一个 DateTime 对象,该对象设置为此计算机上的当前日期和时间,表示为本地时间。

Second

获取此实例所表示日期的秒部分。

Ticks

获取表示此实例的日期和时间的计时周期数。

TimeOfDay

获取此实例的当天的时间。

Today

获取当前日期。

UtcNow

获取一个 DateTime 对象,该对象设置为此计算机上的当前日期和时间,表示为协调通用时间 (UTC)。

Year

获取此实例所表示日期的年份部分。

方法

Add(TimeSpan)

返回一个新的 DateTime,它将指定 TimeSpan 的值添加到此实例的值上。

AddDays(Double)

返回一个新的 DateTime,它将指定的天数加到此实例的值上。

AddHours(Double)

返回一个新的 DateTime,它将指定的小时数加到此实例的值上。

AddMilliseconds(Double)

返回一个新的 DateTime,它将指定的毫秒数加到此实例的值上。

AddMinutes(Double)

返回一个新的 DateTime,它将指定的分钟数加到此实例的值上。

AddMonths(Int32)

返回一个新的 DateTime,它将指定的月数加到此实例的值上。

AddSeconds(Double)

返回一个新的 DateTime,它将指定的秒数加到此实例的值上。

AddTicks(Int64)

返回一个新的 DateTime,它将指定的刻度数加到此实例的值上。

AddYears(Int32)

返回一个新的 DateTime,它将指定的年份数加到此实例的值上。

Compare(DateTime, DateTime)

对两个 DateTime 的实例进行比较,并返回一个指示第一个实例是早于、等于还是晚于第二个实例的整数。

CompareTo(DateTime)

将此实例的值与指定的 DateTime 值相比较,并返回一个整数,该整数指示此实例是早于、等于还是晚于指定的 DateTime 值。

CompareTo(Object)

将此实例的值与包含指定的 DateTime 值的指定对象相比较,并返回一个整数,该整数指示此实例是早于、等于还是晚于指定的 DateTime 值。

DaysInMonth(Int32, Int32)

返回指定年和月中的天数。

Equals(DateTime)

返回一个值,该值指示此实例的值是否等于指定 DateTime 实例的值。

Equals(DateTime, DateTime)

返回一个值,该值指示的两个 DateTime 实例是否具有同一个日期和时间值。

Equals(Object)

返回一个值,该值指示此实例是否等于指定的对象。

FromBinary(Int64)

反序列化一个 64 位二进制值,并重新创建序列化的 DateTime 初始对象。

FromFileTime(Int64)

将指定的 Windows 文件时间转换为等效的本地时间。

FromFileTimeUtc(Int64)

将指定的 Windows 文件时间转换为等效的 UTC 时间。

FromOADate(Double)

返回与指定的 OLE 自动化日期等效的 DateTime

GetDateTimeFormats()

将此实例的值转换为标准日期和时间格式说明符支持的所有字符串表示形式。

GetDateTimeFormats(Char)

将此实例的值转换为指定的标准日期和时间格式说明符支持的所有字符串表示形式。

GetDateTimeFormats(Char, IFormatProvider)

将此实例的值转换为指定的标准日期和时间格式说明符和区域性特定格式信息支持的所有字符串表示形式。

GetDateTimeFormats(IFormatProvider)

将此实例的值转换为标准日期和时间格式说明符和指定的区域性特定格式信息支持的所有字符串表示形式。

GetHashCode()

返回此实例的哈希代码。

GetTypeCode()

返回值类型 TypeCodeDateTime

IsDaylightSavingTime()

指示此 DateTime 实例是否在当前时区的夏时制范围内。

IsLeapYear(Int32)

返回指定的年份是否为闰年的指示。

Parse(ReadOnlySpan<Char>, IFormatProvider, DateTimeStyles)

使用指定的区域性特定格式设置信息和格式类型,将包含日期和时间的字符串表示形式的内存范围转换为其等效的 DateTime

Parse(String)

使用当前区域性的约定将日期和时间的字符串表示形式转换为等效 DateTime 项。

Parse(String, IFormatProvider)

使用指定的区域性特定格式设置信息,将日期和时间的字符串表示形式转换为其等效的 DateTime

Parse(String, IFormatProvider, DateTimeStyles)

使用指定的区域性特定格式设置信息和格式类型,将日期和时间的字符串表示形式转换为其等效的 DateTime

ParseExact(ReadOnlySpan<Char>, ReadOnlySpan<Char>, IFormatProvider, DateTimeStyles)

使用指定的格式、区域性特定的格式信息和样式将日期和时间的指定范围表示形式转换为其等效的 DateTime。 字符串表示形式的格式必须与指定的格式完全匹配,否则会引发异常。

ParseExact(ReadOnlySpan<Char>, String[], IFormatProvider, DateTimeStyles)

使用指定的格式数组、区域性特定的格式信息和样式将日期和时间的指定范围表示形式转换为其等效的 DateTime。 字符串表示形式的格式必须至少与指定的格式之一完全匹配,否则会引发异常。

ParseExact(String, String, IFormatProvider)

使用指定的格式和区域性特定格式信息,将日期和时间的指定字符串表示形式转换为其等效的 DateTime。 字符串表示形式的格式必须与指定的格式完全匹配。

ParseExact(String, String, IFormatProvider, DateTimeStyles)

使用指定的格式、区域性特定的格式信息和样式将日期和时间的指定字符串表示形式转换为其等效的 DateTime。 字符串表示形式的格式必须与指定的格式完全匹配,否则会引发异常。

ParseExact(String, String[], IFormatProvider, DateTimeStyles)

使用指定的格式数组、区域性特定格式信息和样式,将日期和时间的指定字符串表示形式转换为其等效的 DateTime。 字符串表示形式的格式必须至少与指定的格式之一完全匹配,否则会引发异常。

SpecifyKind(DateTime, DateTimeKind)

创建新的 DateTime 对象,该对象具有与指定的 DateTime 相同的刻度数,但是根据指定的 DateTimeKind 值的指示,指定为本地时间或协调世界时 (UTC),或者两者皆否。

Subtract(DateTime)

返回一个新的 TimeSpan,从此实例的值中减去指定的日期和时间。

Subtract(TimeSpan)

返回一个新的 DateTime,从此实例的值中减去指定持续时间。

ToBinary()

将当前 DateTime 对象序列化为一个 64 位二进制值,该值随后可用于重新创建 DateTime 对象。

ToFileTime()

将当前 DateTime 对象的值转换为 Windows 文件时间。

ToFileTimeUtc()

将当前 DateTime 对象的值转换为 Windows 文件时间。

ToLocalTime()

将当前 DateTime 对象的值转换为本地时间。

ToLongDateString()

将当前 DateTime 对象的值转换为其等效的长日期字符串表示形式。

ToLongTimeString()

将当前 DateTime 对象的值转换为其等效的长时间字符串表示形式。

ToOADate()

将此实例的值转换为等效的 OLE 自动化日期。

ToShortDateString()

将当前 DateTime 对象的值转换为其等效的短日期字符串表示形式。

ToShortTimeString()

将当前 DateTime 对象的值转换为其等效的短时间字符串表示形式。

ToString()

使用当前的区域性格式约定将当前 DateTime 对象的值转换为它的等效字符串表示形式。

ToString(IFormatProvider)

使用指定的区域性特定格式信息将当前 DateTime 对象的值转换为它的等效字符串表示形式。

ToString(String)

使用指定的格式和当前区域性的格式约定将当前 DateTime 对象的值转换为它的等效字符串表示形式。

ToString(String, IFormatProvider)

使用指定的格式和区域性特定格式信息将当前 DateTime 对象的值转换为它的等效字符串表示形式。

ToUniversalTime()

将当前 DateTime 对象的值转换为协调世界时 (UTC)。

TryFormat(Span<Char>, Int32, ReadOnlySpan<Char>, IFormatProvider)

尝试将当前日期/时间实例的值的格式化为提供的字符范围。

TryParse(ReadOnlySpan<Char>, DateTime)

将日期和时间的指定字符范围转换为其等效的 DateTime,并返回一个指示转换是否成功的值。

TryParse(ReadOnlySpan<Char>, IFormatProvider, DateTimeStyles, DateTime)

使用指定的区域性特定格式信息和格式设置样式,将日期和时间的范围表示形式转换为其等效的 DateTime,并返回一个指示转换是否成功的值。

TryParse(String, DateTime)

将日期和时间的指定字符串表示形式转换为其 DateTime 等效项,并返回一个指示转换是否成功的值。

TryParse(String, IFormatProvider, DateTimeStyles, DateTime)

使用指定的区域性特定格式信息和格式设置样式,将日期和时间的指定字符串表示形式转换为其 DateTime 等效项,并返回一个指示转换是否成功的值。

TryParseExact(ReadOnlySpan<Char>, ReadOnlySpan<Char>, IFormatProvider, DateTimeStyles, DateTime)

使用指定的格式、区域性特定的格式信息和样式将日期和时间的指定范围表示形式转换为其等效的 DateTime。 字符串表示形式的格式必须与指定的格式完全匹配。 该方法返回一个指示转换是否成功的值。

TryParseExact(ReadOnlySpan<Char>, String[], IFormatProvider, DateTimeStyles, DateTime)

将日期和时间的指定字符范围转换为其等效的 DateTime,并返回一个指示转换是否成功的值。

TryParseExact(String, String, IFormatProvider, DateTimeStyles, DateTime)

使用指定的格式、区域性特定的格式信息和样式将日期和时间的指定字符串表示形式转换为其等效的 DateTime。 字符串表示形式的格式必须与指定的格式完全匹配。 该方法返回一个指示转换是否成功的值。

TryParseExact(String, String[], IFormatProvider, DateTimeStyles, DateTime)

使用指定的格式数组、区域性特定格式信息和样式,将日期和时间的指定字符串表示形式转换为其等效的 DateTime。 字符串表示形式的格式必须至少与指定的格式之一完全匹配。 该方法返回一个指示转换是否成功的值。

运算符

Addition(DateTime, TimeSpan)

将指定的时间间隔加到指定的日期和时间以生成新的日期和时间。

Equality(DateTime, DateTime)

确定 DateTime 的两个指定的实例是否相等。

GreaterThan(DateTime, DateTime)

确定指定的 DateTime 是否晚于另一个指定的 DateTime

GreaterThanOrEqual(DateTime, DateTime)

确定一个指定的 DateTime 表示的日期和时间等于还是晚于另一个指定的 DateTime

Inequality(DateTime, DateTime)

确定 DateTime 的两个指定的实例是否不等。

LessThan(DateTime, DateTime)

确定指定的 DateTime 是否早于另一个指定的 DateTime

LessThanOrEqual(DateTime, DateTime)

确定一个指定的 DateTime 表示的日期和时间等于还是早于另一个指定的 DateTime

Subtraction(DateTime, DateTime)

将指定的日期和时间与另一个指定的日期和时间相减,返回一个时间间隔。

Subtraction(DateTime, TimeSpan)

从指定的日期和时间减去指定的时间间隔,返回新的日期和时间。

显式接口实现

IComparable.CompareTo(Object)

将当前实例与同一类型的另一个对象进行比较,并返回一个整数,该整数指示当前实例在排序顺序中的位置是位于另一个对象之前、之后还是与其位置相同。

IConvertible.GetTypeCode()

返回此实例的 TypeCode

IConvertible.ToBoolean(IFormatProvider)

不支持此转换。 尝试使用此方法将引发 InvalidCastException

IConvertible.ToByte(IFormatProvider)

不支持此转换。 尝试使用此方法将引发 InvalidCastException

IConvertible.ToChar(IFormatProvider)

不支持此转换。 尝试使用此方法将引发 InvalidCastException

IConvertible.ToDateTime(IFormatProvider)

返回当前 DateTime 对象。

IConvertible.ToDecimal(IFormatProvider)

不支持此转换。 尝试使用此方法将引发 InvalidCastException

IConvertible.ToDouble(IFormatProvider)

不支持此转换。 尝试使用此方法将引发 InvalidCastException

IConvertible.ToInt16(IFormatProvider)

不支持此转换。 尝试使用此方法将引发 InvalidCastException

IConvertible.ToInt32(IFormatProvider)

不支持此转换。 尝试使用此方法将引发 InvalidCastException

IConvertible.ToInt64(IFormatProvider)

不支持此转换。 尝试使用此方法将引发 InvalidCastException

IConvertible.ToSByte(IFormatProvider)

不支持此转换。 尝试使用此方法将引发 InvalidCastException

IConvertible.ToSingle(IFormatProvider)

不支持此转换。 尝试使用此方法将引发 InvalidCastException

IConvertible.ToType(Type, IFormatProvider)

将当前 DateTime 对象转换为指定类型的对象。

IConvertible.ToUInt16(IFormatProvider)

不支持此转换。 尝试使用此方法将引发 InvalidCastException

IConvertible.ToUInt32(IFormatProvider)

不支持此转换。 尝试使用此方法将引发 InvalidCastException

IConvertible.ToUInt64(IFormatProvider)

不支持此转换。 尝试使用此方法将引发 InvalidCastException

ISerializable.GetObjectData(SerializationInfo, StreamingContext)

使用序列化当前的 SerializationInfo 对象所需的所有数据填充 DateTime 对象。

适用于

线程安全性

此类型的所有成员都是线程安全的。 似乎修改实例状态的成员实际上返回使用新值初始化的新实例。 与任何其他类型一样,读取和写入包含此类型的实例的共享变量必须受到锁的保护,以确保线程安全。

另请参阅