DateTime 结构

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

**命名空间:**System
**程序集:**mscorlib(在 mscorlib.dll 中)

语法

声明
<SerializableAttribute> _
Public Structure DateTime
    Implements IComparable, IFormattable, IConvertible, ISerializable, _
    IComparable(Of DateTime), IEquatable(Of DateTime)
用法
Dim instance As 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>
/** @attribute SerializableAttribute() */ 
public final class DateTime extends ValueType implements IComparable, IFormattable, 
    IConvertible, ISerializable, IComparable<DateTime>, IEquatable<DateTime>
JScript 支持使用结构,但不支持进行新的声明。

备注

DateTime 值类型表示值范围在公元(基督纪元)0001 年 1 月 1 日午夜 12:00:00 到公元 (C.E.) 9999 年 12 月 31 日晚上 11:59:59 之间的日期和时间

时间值以 100 毫微秒为单位(该单位称为刻度)进行计量,而特定日期是自 GregorianCalendar 日历中公元 (C.E.) 0001 年 1 月 1 日午夜 12:00 以来的刻度数。例如,刻度值 31241376000000000L 表示 0100 年 1 月 1 日(星期五)午夜 12:00:00。DateTime 值始终在显式或默认日历的上下文中表示。

版本注意事项

在 .NET Framework 2.0 版以前,DateTime 结构包含一个 64 位字段,该字段由一个未使用的 2 位字段和一个私有字段 Ticks 串联组成,Ticks 字段是一个 62 位无符号字段,其中包含表示日期和时间的刻度数。Ticks 字段的值可通过 Ticks 属性获取。

从 .NET Framework 2.0 开始,DateTime 结构包含一个由私有字段 Kind 和 Ticks 字段串联组成的 64 位字段。Kind 字段是一个 2 位字段,它指示 DateTime 结构是表示本地时间、协调通用时间 (UTC) 还是 UTC 和本地时间都未指定。Kind 字段用于处理本地时间和 UTC 时间之间的转换,但不用于时间的比较或算术运算。Kind 字段的值可通过 Kind 属性获取。

DateTime 值

DateTime 类型的时间值描述通常使用协调通用时间 (UTC) 标准来表达,它是格林威治标准时间 (GMT) 的国际识别名。协调通用时间是在经度零度(即 UTC 原点)测量到的时间。夏时制不适用于 UTC。

本地时间是相对于特定时区而言。时区与时区偏移量关联,它是时区从 UTC 原点算起的以小时为单位的偏移量。此外,本地时间有可能受夏时制影响,夏时制会对日长增加或减少一小时。因此,本地时间的计算是将时区偏移量加上 UTC,如有必要,再根据夏时制进行调整。UTC 原点的时区偏移量为零。

UTC 时间适合于计算、比较日期和时间,以及将日期和时间存储在文件中。本地时间适合于在用户界面中显示。

如果 DateTime 对象的 Kind 属性为 Unspecified,则其未指定表示的时间为本地时间还是 UTC 时间。各个 DateTime 成员针对该成员相应地处理未指定的时间。

DateTime 操作

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

本地时间和 UTC 时间之间的转换运算会考虑夏时制,但是算术和比较运算无需考虑。

DateTime 对象的计算和比较仅当这些对象表示同一时区中的时间时才有意义。因此,如果没有为 DateTime 对象指定时区,则假设开发人员有某种外部机制(如显式变量或策略)可用于确定创建该对象所在的时区。

每个 DateTime 成员都隐式使用公历执行其操作,例外是指定日历的构造函数以及使用从 IFormatProvider 派生的参数(如 System.Globalization.DateTimeFormatInfo)的方法,该参数隐式指定日历。

DateTime 类型中的成员所执行的运算会考虑闰年和月中天数等细节。

DateTime 与 TimeSpan

DateTime 值类型与 TimeSpan 值类型的差异在于 DateTime 表示时间上的一刻,而 TimeSpan 表示时间间隔。例如,这表示您可以从 DateTime 的一个实例减去另一个实例来获得它们之间的时间间隔。也可以将正的 TimeSpan 加到当前的 DateTime 来计算将来的日期。

可以向 DateTime 对象增加或减少一个时间间隔。时间间隔可为负,也可为正,可以用刻度或秒等为单位表示,也可表示为 TimeSpan 对象。

COM Interop 注意事项

一个 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 对象的错误日期。

实现的接口

此类型实现接口 IComparableIComparableIFormattableIConvertible。使用 Convert 类进行转换,而不是使用此类型的 IConvertible 显式接口成员实现。

示例

下面的代码示例演示如何大致比较等效的 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 

线程安全

此类型的任何公共静态(Visual Basic 中的 Shared)成员都是线程安全的,但不保证所有实例成员都是线程安全的。

平台

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 并不是对每个平台的所有版本都提供支持。有关受支持版本的列表,请参见系统要求

版本信息

.NET Framework

受以下版本支持:2.0、1.1、1.0

.NET Compact Framework

受以下版本支持:2.0、1.0

请参见

参考

DateTime 成员
System 命名空间
TimeSpan
Calendar
GetUtcOffset