DateTime 構造体
アセンブリ: mscorlib (mscorlib.dll 内)

<SerializableAttribute> _ Public Structure DateTime Implements IComparable, IFormattable, IConvertible, ISerializable, _ IComparable(Of DateTime), IEquatable(Of DateTime)
[SerializableAttribute] public struct DateTime : IComparable, IFormattable, IConvertible, ISerializable, IComparable<DateTime>, IEquatable<DateTime>
[SerializableAttribute] public value class DateTime : IComparable, IFormattable, IConvertible, ISerializable, IComparable<DateTime>, IEquatable<DateTime>

DateTime 値型は、A.D. (西暦紀元) 0001 年 1 月 1 日の午前 00:00:00 から A.D. (西暦紀元) 9999 年 12 月 31 日の午後 11:59:59 までの間の値で日付と時刻を表します。
時刻値は 100 ナノ秒単位 (タイマ刻み) で表し、日付は GregorianCalendar 暦の A.D. (西暦紀元) 1 年 1 月 1 日の午前 00:00 からのタイマ刻み数で表します。たとえば、タイマ刻み値 31241376000000000L は、0100 年 1 月 1 日 (金曜日) の深夜 12:00:00 を表します。DateTime 値は、常に、明示的な暦または既定の暦のコンテキストで表されます。
バージョンの考慮事項以前のバージョンの .NET Framework では、DateTime 構造体に、プライベートの Ticks フィールド (62 ビットの符号なしフィールドで日付と時刻を表すタイマ刻み数を格納) と、未使用の 2 ビット フィールドとが連結された、合わせて 64 ビットのフィールドが格納されていました。Ticks フィールドの値は、Ticks プロパティで取得できます。
.NET Framework 2.0 以降では、DateTime 構造体には、Ticks フィールドとプライベートの Kind フィールドとが連結された、合わせて 64 ビットのフィールドが格納されます。Kind フィールドは、DateTime 構造体によって表される時刻が "現地時刻である"、"世界協定時刻 (UTC) である"、または、"そのいずれにも該当しない" のいずれかを示す 2 ビットのフィールドです。Kind フィールドは、主に現地時刻と UTC 時刻との間の変換時に使用され、時刻の比較や算術計算には使用されません。Kind フィールドの値は、Kind プロパティで取得できます。
DateTime 型の時刻値は、多くの場合、世界協定時刻 (UTC) を使用して表されます。世界協定時刻はグリニッジ標準時 (GMT) と呼ばれることもあります。世界協定時刻は、経度 0°を基準として計算された時刻です。UTC は夏時間の影響を受けません。
現地時刻は、特定のタイム ゾーンを基準に計算されます。タイム ゾーンには、特定のオフセット値 (UTC 基準点からの時間のずれ) が割り当てられます。また、現地時刻は、夏時間を加味し、一日の長さを 1 時間遅らせたり、早めたりすることによって調整される場合があります。したがって、現地時刻は、UTC にタイム ゾーン オフセットを加算し、必要に応じて夏時間を調整した時刻になります。UTC 基準点におけるタイム ゾーン オフセットはゼロです。
UTC 時刻は、日時の計算や比較、およびファイルのタイムスタンプを追跡する目的に適しています。これに対し、現地時刻は、ユーザー インターフェイスでの表示に適しています。
時刻が現地時刻であるか、UTC 時刻であるかが不定の場合、DateTime オブジェクトの Kind プロパティは Unspecified になります。現地時刻であるか UTC 時刻であるかが不定の時刻は、DateTime の対応するメンバによって適切に処理されます。
Add や Subtract など、DateTime 構造体を使用した計算では、この構造体の値そのものが変更されるわけではありません。代わりに、計算結果を値として保持する、新しい DateTime 構造体が返されます。
夏時間は、現地時刻と UTC 時刻と間の変換時にのみ考慮され、日時の比較や算術計算時には考慮されません。
DateTime オブジェクトの計算および比較では、対象となる複数のオブジェクトが同じタイム ゾーンの時刻を表している場合にのみ、意味のある結果を得ることができます。そのため、このオブジェクトに対してタイム ゾーンを指定しない場合は、開発者側で、専用の変数を用意したり、特別な方針を設けるなど、なんらかのメカニズムによって、DateTime オブジェクトの作成されたタイム ゾーンを判別できるようにする必要があります。
DateTime の各メンバは、暗黙的にグレゴリオ暦を使用して演算を実行します。ただし、暦を指定するコンストラクタや、System.Globalization.DateTimeFormatInfo などの、IFormatProvider から派生したパラメータで暗黙的に暦を指定するメソッドは例外です。
DateTime 値型と TimeSpan 値型の違う点は、DateTime が瞬間を表し、TimeSpan が時間間隔を表すことです。つまり、たとえば DateTime の 1 つのインスタンスを別のインスタンスから減算すると、それら 2 つのインスタンス間の時間間隔を取得できます。または、現在の DateTime に正の TimeSpan を加算すると将来の日付が算出されます。
DateTime オブジェクトでは、時間間隔を加算したり、減算したりできます。時間間隔の指定には、正数や負数、タイマ刻み数や秒数、または TimeSpan オブジェクトも使用できます。
DateTime 値は、一度、COM アプリケーションに転送し、その後、再びマネージ アプリケーションに戻すことができます。これを "値がラウンドトリップした" と言います。しかし、DateTime 値に時刻しか指定されていないと、期待どおりに値がラウンドトリップしてくれません。
時刻だけ (たとえば、午後 3:00) をラウンドトリップさせた場合、最終的に返る日時は西暦 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 の値を比較して、一定の小さな範囲の許容誤差において "等しい" と判定する方法を次のコード例に示します。
Class DateTimeTester 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 'RoughlyEquals Public Shared Sub Main() 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 [true]: " + CStr(RoughlyEquals(d1, d1, window, freq))) Console.WriteLine("d1 ~= d2 [false]: " + CStr(RoughlyEquals(d1, d2, window, freq))) Console.WriteLine("d1 ~= d3 [false]: " + CStr(RoughlyEquals(d1, d3, window, freq))) Console.WriteLine("d1 ~= d4 [true]: " + CStr(RoughlyEquals(d1, d4, window, freq))) Console.WriteLine("d1 ~= d5 [true]: " + CStr(RoughlyEquals(d1, d5, window, freq))) Console.WriteLine("d1 ~= d6 [false]: " + CStr(RoughlyEquals(d1, d6, window, freq))) Console.WriteLine("d1 ~= d7 [false]: " + CStr(RoughlyEquals(d1, d7, window, freq))) Console.WriteLine("d1 ~= d8 [true]: " + CStr(RoughlyEquals(d1, d8, window, freq))) Console.WriteLine("d1 ~= d9 [true]: " + CStr(RoughlyEquals(d1, d9, window, freq))) End Sub 'Main End Class 'DateTimeTester
class DateTimeTester { 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 Main() { 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 [true]: " + RoughlyEquals(d1, d1, window, freq)); Console.WriteLine("d1 ~= d2 [false]: " + RoughlyEquals(d1, d2, window, freq)); Console.WriteLine("d1 ~= d3 [false]: " + RoughlyEquals(d1, d3, window, freq)); Console.WriteLine("d1 ~= d4 [true]: " + RoughlyEquals(d1, d4, window, freq)); Console.WriteLine("d1 ~= d5 [true]: " + RoughlyEquals(d1, d5, window, freq)); Console.WriteLine("d1 ~= d6 [false]: " + RoughlyEquals(d1, d6, window, freq)); Console.WriteLine("d1 ~= d7 [false]: " + RoughlyEquals(d1, d7, window, freq)); Console.WriteLine("d1 ~= d8 [true]: " + RoughlyEquals(d1, d8, window, freq)); Console.WriteLine("d1 ~= d9 [true]: " + RoughlyEquals(d1, d9, window, freq)); } }
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; } int main() { 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 [true]: {0}", RoughlyEquals( d1, d1, window, freq ) ); Console::WriteLine( "d1 ~= d2 [false]: {0}", RoughlyEquals( d1, d2, window, freq ) ); Console::WriteLine( "d1 ~= d3 [false]: {0}", RoughlyEquals( d1, d3, window, freq ) ); Console::WriteLine( "d1 ~= d4 [true]: {0}", RoughlyEquals( d1, d4, window, freq ) ); Console::WriteLine( "d1 ~= d5 [true]: {0}", RoughlyEquals( d1, d5, window, freq ) ); Console::WriteLine( "d1 ~= d6 [false]: {0}", RoughlyEquals( d1, d6, window, freq ) ); Console::WriteLine( "d1 ~= d7 [false]: {0}", RoughlyEquals( d1, d7, window, freq ) ); Console::WriteLine( "d1 ~= d8 [true]: {0}", RoughlyEquals( d1, d8, window, freq ) ); Console::WriteLine( "d1 ~= d9 [true]: {0}", RoughlyEquals( d1, d9, window, freq ) ); }
class DateTimeTester { public static boolean RoughlyEquals(DateTime time, DateTime timeWithWindow, int windowInSeconds, int frequencyInSeconds) { long delta = (long)((TimeSpan)timeWithWindow.Subtract(time)). get_TotalSeconds() % frequencyInSeconds; delta = delta > windowInSeconds ? frequencyInSeconds - delta : delta; return (System.Convert.ToBoolean(System.Math.Abs(delta) < windowInSeconds)); } //RoughlyEquals public static void main(String[] args) { int window = 10; int freq = 60 * 60 * 2; // 2 hours; DateTime d1 = DateTime.get_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 [true]: " + RoughlyEquals(d1, d1, window, freq)); Console.WriteLine("d1 ~= d2 [false]: " + RoughlyEquals(d1, d2, window, freq)); Console.WriteLine("d1 ~= d3 [false]: " + RoughlyEquals(d1, d3, window, freq)); Console.WriteLine("d1 ~= d4 [true]: " + RoughlyEquals(d1, d4, window, freq)); Console.WriteLine("d1 ~= d5 [true]: " + RoughlyEquals(d1, d5, window, freq)); Console.WriteLine("d1 ~= d6 [false]: " + RoughlyEquals(d1, d6, window, freq)); Console.WriteLine("d1 ~= d7 [false]: " + RoughlyEquals(d1, d7, window, freq)); Console.WriteLine("d1 ~= d8 [true]: " + RoughlyEquals(d1, d8, window, freq)); Console.WriteLine("d1 ~= d9 [true]: " + RoughlyEquals(d1, d9, window, freq)); } //main } //DateTimeTester


Windows 98, Windows 2000 SP4, Windows CE, Windows Millennium Edition, Windows Mobile for Pocket PC, Windows Mobile for Smartphone, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition
開発プラットフォームの中には、.NET Framework によってサポートされていないバージョンがあります。サポートされているバージョンについては、「システム要件」を参照してください。


- DateTime 構造体のページへのリンク