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 : IComparable, IConvertible, IFormattable
public value class DateTime : IComparable, IComparable<DateTime>, IEquatable<DateTime>, IFormattable
public struct DateTime : IComparable, IComparable<DateTime>, IConvertible, IEquatable<DateTime>, IFormattable
public struct DateTime : IComparable, IComparable<DateTime>, IConvertible, IEquatable<DateTime>, IFormattable, System.Runtime.Serialization.ISerializable
public struct DateTime : IComparable, IComparable<DateTime>, IConvertible, IEquatable<DateTime>, ISpanFormattable, 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
[<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 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 用途的主题:

值类型表示日期和时间,其值范围为 0001 年 1 月 1 日午夜 DateTime) 00:00:00 ( (Anno Domini (Common Era) 到 9999 年 12 月 31 日下午 11:59:59。 晚上 11:59:59。

时间值以 100 纳秒为单位(称为时钟周期)进行度量。 特定日期是自 0001 年 1 月 1 日午夜 12:00 以来的滴答数。 (日历) C.E.) 。 GregorianCalendar 该数字不包括将按闰秒添加的刻度。 例如,时钟周期值 31241376000000000L 表示星期五,0100 年 1 月 1 日午夜 12:00:00。 DateTime值始终在显式或默认日历的上下文中表示。

备注

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

可以在 GitHub 上的文档存储库中的 Visual Basic或 C# 中查看本文中整个示例集的GitHub。

备注

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

初始化 DateTime 对象

可以通过许多不同的方式将初始 DateTime 值分配给新值:

  • 调用构造函数(在构造函数中指定值的参数)或使用隐式无参数构造函数。
  • DateTime 分配给属性或方法的返回值。
  • 从值的 DateTime 字符串表示形式分析值。
  • 使用Visual Basic特定语言功能实例化 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);

若要将 初始化为其默认值,请调用结构的隐式无 DateTime DateTime 参数构造函数。 (有关值类型的隐式无参数构造函数的详细信息,请参阅值类型 .) 某些编译器还支持声明值,而无需显式为其赋值 DateTime 。 创建不带显式初始化的值也会导致默认值。 以下示例演示 C# 和 Visual Basic 中的隐式无参数构造函数,以及未在 Visual Basic DateTime DateTime 中赋值的声明。

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));
分配计算值

你可以为 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;
分析表示 DateTime 的字符串

、、 Parse ParseExactTryParse TryParseExact 方法均将字符串转换为其等效的日期和时间值。 以下示例使用 和 Parse ParseExact 方法分析字符串并将其转换为 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);

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

特定于语言的语法Visual Basic

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

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

DateTime 值及其字符串表示形式

在内部,所有值都表示为自 DateTime 20001 年 1 月 1 (日午夜 12: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
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
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
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
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
Dim date1 As Date = #3/1/2008 7:00AM#
Console.WriteLine(date1.ToString("yyyyMMddTHH:mm:ssZ"))
' Displays 20080301T07:00:00Z

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

分析字符串中的日期时间值

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

  • 日期和时间采用各种形式,并反映了当前区域性或特定区域性的约定。 例如,应用程序允许其当前区域性为 en-us 的用户将日期值输入为 "12/15/2013" 或 "12 月15日,2013"。 它允许当前区域性为 en 的用户将日期值输入为 "15/12/2013" 或 "15 12 月12日 2013"。

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

使用 Parse 或方法可以 TryParse 将字符串从区域性使用的一个通用日期和时间格式转换为一个 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.
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
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}");
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 值,该值指示转换是成功还是失败。 TryParse TryParseExact 在性能非常重要的情况下,应使用或方法。 日期和时间字符串的分析操作往往会产生较高的故障率,并且异常处理开销较高。 如果用户输入字符串或来自未知源,请使用这些方法。

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

DateTime 值

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

本地时间相对于特定时区。 时区与时区偏移量关联。 时区偏移量是从 UTC 原点开始,以小时为单位的时间范围的位移。 此外,还可以根据夏令时(添加或减去时间间隔调整)来影响本地时间。 本地时间是通过将时区偏移量添加到 UTC 并调整夏令时(如有必要)来计算的。 UTC 原点的时区偏移量为零。

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

如果 Kind 对象的属性 DateTime 为,则 DateTimeKind.Unspecified 指示表示的时间是本地时间、UTC 时间还是其他某个时区中的时间。

日期时间解析

备注

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

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

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

string output = "";
for (int ctr = 0; ctr <= 20; ctr++)
{
    output += String.Format($"{DateTime.Now.Millisecond}\n");
    // Introduce a delay loop.
    for (int delay = 0; delay <= 1000; delay++)
    { }

    if (ctr == 10)
    {
        output += "Thread.Sleep called...\n";
        System.Threading.Thread.Sleep(5);
    }
}
Console.WriteLine(output);
// Press "Run" to see the output.
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 结构(如或)的计算 Add Subtract 不会修改结构的值。 相反,计算返回一个新的 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 类,它们都派生自 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
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
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

通过使用日期和时间元素实例化值 (特定日历的年、月、日) 数,可以调用包含 参数的 DateTime DateTime构造函数,并传递给它一个表示该日历的对象。 calendar Calendar 以下示例使用日历中的日期和时间 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
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
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
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...
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. 通过调用 或 重载来 ParseExact 分析 TryParseExact 数据。 指定 CultureInfo.InvariantCulture 作为 provider 参数,并使用在转换过程中用于参数的相同 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...
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 来实例化新 DateTime(Int64) 对象。
  2. 如果 DateTime 值表示一个时刻,请通过调用 方法将其从 UTC 转换为本地 ToLocalTime 时间。

以下示例将值数组保留为美国太平洋时区 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...
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
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 化它。 反初始化后,通过调用 方法将其从 UTC 转换为本地 ToLocalTime 时间。 以下示例使用 类在美国太平洋标准时区中的系统上序列化数据,并在美国中部标准区域中的系统上反序列 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...
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
    <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 数组。 可以在 Visual Basic 上的文档存储库中查看本文中整个示例集的Visual Basic C# GitHub。

然后,可以使用 结构 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
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
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

DateTime TimeSpan 值类型不同,因为 表示 DateTime 时刻,而 TimeSpan 表示时间间隔。 可以从另一个实例中减去 一个实例, DateTime 以获取 TimeSpan 表示它们之间的时间间隔的 对象。 或者,可以将正值 TimeSpan 添加到当前 , DateTime 以获取 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
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日 在下午3:00,而不是公元0001年1月1日 下午3:00 在仅指定时间时,.NET Framework 和 COM 将假定为默认日期。 但是,COM 系统假定基准日期为公元1899年12月30日,而 .NET Framework 假设基准日期为公元0001年1月1日。

当只将时间从 .NET Framework 传递到 com 时,会执行特殊处理,将时间转换为 com 使用的格式。 如果仅将时间从 COM 传递到 .NET Framework,则不会执行任何特殊处理,因为这样会损坏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 对象。

适用于

线程安全性

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

另请参阅