次の方法で共有


System.DateTime.ToBinary メソッドと FromBinary メソッド

この記事では、この API のリファレンス ドキュメントに補足的な解説を提供します。

ToBinary メソッドを使用して、現在のDateTime オブジェクトの値をバイナリ値に変換します。 その後、バイナリ値と FromBinary メソッドを使用して、元の DateTime オブジェクトを再作成します。

重要

場合によっては、DateTime メソッドによって返されるFromBinary値が、DateTime メソッドに指定された元のToBinary値と同じではありません。 詳細については、次のセクション「ローカル時刻の調整」を参照してください。

DateTime構造体は、プライベート Kind フィールドで構成されます。これは、指定された時刻値がローカル時刻、協定世界時 (UTC) に基づいているか、どちらもプライベート Ticks フィールドに連結されていないかを示します。このフィールドには、日付と時刻を指定する 100 ナノ秒のティック数が含まれます。

現地時刻の調整

現地時刻は、ローカル タイム ゾーンに調整された協定世界時であり、DateTime プロパティの値がKindLocal構造体によって表されます。 DateTime メソッドによって生成されたバイナリ表現からローカル ToBinary値を復元する場合、FromBinary メソッドは再作成された値を元の値と等しくしないように調整できます。 これは、次の条件下で発生する可能性があります。

  • ローカル DateTime オブジェクトが ToBinary メソッドによって 1 つのタイム ゾーンでシリアル化された後、 FromBinary メソッドによって別のタイム ゾーンで逆シリアル化された場合、結果の DateTime オブジェクトによって表されるローカル時刻は、2 番目のタイム ゾーンに自動的に調整されます。

    たとえば、現地時刻の午後 3 時を表す DateTime オブジェクトがあるとします。米国太平洋タイム ゾーンで実行されているアプリケーションでは、 ToBinary メソッドを使用して、その DateTime オブジェクトをバイナリ値に変換します。 米国東部タイム ゾーンで実行されている別のアプリケーションでは、 FromBinary メソッドを使用してバイナリ値を新しい DateTime オブジェクトに変換します。 新しい DateTime オブジェクトの値は午後 6 時です。これは、元の 3 P.M. 値と同じ時点を表しますが、東部標準時ゾーンの現地時刻に調整されます。

  • ローカル DateTime 値のバイナリ表現が、 FromBinary が呼び出されるシステムのローカル タイム ゾーンで無効な時刻を表す場合、時刻は有効になるように調整されます。

    たとえば、標準時から夏時間への移行は、2010 年 3 月 14 日午前 2 時 (時刻が 1 時間進む午前 3 時) に、米国の太平洋標準時ゾーンで発生します。この時間間隔は無効な時間です。つまり、このタイム ゾーンに存在しない時間間隔です。 次の例では、この範囲内の時刻が 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($"{localDate} is an invalid time in the {TimeZoneInfo.Local.StandardName} zone.");
    
          DateTime localDate2 = DateTime.FromBinary(binLocal);
          Console.WriteLine($"{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