System.DateTime.ToBinary 和 FromBinary 方法

本文提供了此 API 参考文档的补充说明。

ToBinary使用该方法将当前DateTime对象的值转换为二进制值。 随后,使用二进制值和 FromBinary 方法重新创建原始 DateTime 对象。

重要

在某些情况下,DateTime该方法返回FromBinary的值与提供给ToBinary该方法的原始DateTime值不同。 有关详细信息,请参阅下一部分“本地时间调整”。

DateTime结构由专用Kind字段组成,该字段指示指定的时间值是基于本地时间、协调世界时(UTC),还是两者都与专用Ticks字段连接,该字段包含指定日期和时间的 100 纳秒时钟周期的数目。

本地时间调整

本地时间是调整为本地时区的协调世界时,由 DateTimeKind 属性具有值 Local的结构表示。 从该方法生成的ToBinary二进制表示形式还原本地DateTime值时,该方法FromBinary可以调整重新创建的值,使其不等于原始值。 在下列条件下,可能会出现这种情况:

  • DateTime如果本地对象由ToBinary该方法在一个时区序列化,然后通过FromBinary该方法反序列化在不同的时区,则由生成的DateTime对象表示的本地时间将自动调整为第二个时区。

    例如,请考虑表示 DateTime 本地时间下午 3 点的对象。在美国太平洋时区中执行的应用程序使用 ToBinary 该方法将该 DateTime 对象转换为二进制值。 另一个在美国东部时区中执行的应用程序随后使用 FromBinary 该方法将二进制值转换为新 DateTime 对象。 新 DateTime 对象的值为 6 P.M.,表示与原始 3 P.M. 值相同的时间点,但调整为东部时区的本地时间。

  • 如果本地 DateTime 值的二进制表示无效时间,则调用的 FromBinary 系统的本地时区中的时间无效,则调整时间以便有效。

    例如,从标准时间到夏令时转换发生在 2010 年 3 月 14 日上午 2:00 的美国太平洋时区,时间提前一小时,到凌晨 3:00。此小时间隔是无效的时间,即此时区中不存在的时间间隔。 以下示例显示,当属于此范围的时间由 ToBinary 该方法转换为二进制值,然后由 FromBinary 该方法还原时,原始值将调整为成为有效时间。 如示例所示,可以通过将 TimeZoneInfo.IsInvalidTime 特定日期和时间值传递给方法来确定特定日期和时间值是否可能受到修改。

    using System;
    
    public class Example
    {
       public static void Main()
       {
          DateTime localDate = new DateTime(2010, 3, 14, 2, 30, 0, DateTimeKind.Local);
          long binLocal = localDate.ToBinary();
          if (TimeZoneInfo.Local.IsInvalidTime(localDate))
             Console.WriteLine("{0} is an invalid time in the {1} zone.",
                               localDate,
                               TimeZoneInfo.Local.StandardName);
    
          DateTime localDate2 = DateTime.FromBinary(binLocal);
          Console.WriteLine("{0} = {1}: {2}",
                            localDate, localDate2, localDate.Equals(localDate2));
       }
    }
    // The example displays the following output:
    //    3/14/2010 2:30:00 AM is an invalid time in the Pacific Standard Time zone.
    //    3/14/2010 2:30:00 AM = 3/14/2010 3:30:00 AM: False
    
    open System
    
    let localDate = DateTime(2010, 3, 14, 2, 30, 0, DateTimeKind.Local)
    let binLocal = localDate.ToBinary()
    if TimeZoneInfo.Local.IsInvalidTime localDate then
        printfn $"{localDate} is an invalid time in the {TimeZoneInfo.Local.StandardName} zone."
    
    let localDate2 = DateTime.FromBinary binLocal
    printfn $"{localDate} = {localDate2}: {localDate.Equals localDate2}"
    
    // The example displays the following output:
    //    3/14/2010 2:30:00 AM is an invalid time in the Pacific Standard Time zone.
    //    3/14/2010 2:30:00 AM = 3/14/2010 3:30:00 AM: False
    
    Module Example
       Public Sub Main()
          Dim localDate As Date = DateTime.SpecifyKind(#03/14/2010 2:30AM#, DateTimeKind.Local)
          Dim binLocal As Long = localDate.ToBinary()
          If TimeZoneInfo.Local.IsInvalidTime(localDate) Then
             Console.WriteLine("{0} is an invalid time in the {1} zone.", _
                               localDate, _
                               TimeZoneInfo.Local.StandardName)
          End If
          Dim localDate2 As Date = DateTime.FromBinary(binLocal)
          Console.WriteLine("{0} = {1}: {2}", _
                            localDate, localDate2, localDate.Equals(localDate2))
       End Sub
    End Module
    ' The example displays the following output:
    '    3/14/2010 2:30:00 AM is an invalid time in the Pacific Standard Time zone.
    '    3/14/2010 2:30:00 AM = 3/14/2010 3:30:00 AM: False