• C#中的DateTime


    一、DateTime是值类型还是引用类型的探索

    二、了解DateTime结构体

    三、DateTime.Now和DateTime.UtcNow是怎么计算出来的

    一、DateTime是值类型还是引用类型的探索

         DateTime是值类型,因为DateTime是结构体,而结构体继承自System.ValueType,属于值类型

         

      1 [Serializable, __DynamicallyInvokable]
      2 public struct DateTime : IComparable, IFormattable, IConvertible, ISerializable, IComparable<DateTime>, IEquatable<DateTime>
      3 {
      4     // Fields
      5     private ulong dateData;
      6     private const string DateDataField = "dateData";
      7     private const int DatePartDay = 3;
      8     private const int DatePartDayOfYear = 1;
      9     private const int DatePartMonth = 2;
     10     private const int DatePartYear = 0;
     11     private const int DaysPer100Years = 0x8eac;
     12     private const int DaysPer400Years = 0x23ab1;
     13     private const int DaysPer4Years = 0x5b5;
     14     private const int DaysPerYear = 0x16d;
     15     private const int DaysTo10000 = 0x37b9db;
     16     private const int DaysTo1601 = 0x8eac4;
     17     private const int DaysTo1899 = 0xa9559;
     18     private static readonly int[] DaysToMonth365;
     19     private static readonly int[] DaysToMonth366;
     20     private const long DoubleDateOffset = 0x85103c0cb83c000L;
     21     private const long FileTimeOffset = 0x701ce1722770000L;
     22     private const ulong FlagsMask = 13835058055282163712L;
     23     private const ulong KindLocal = 9223372036854775808L;
     24     private const ulong KindLocalAmbiguousDst = 13835058055282163712L;
     25     private const int KindShift = 0x3e;
     26     private const ulong KindUnspecified = 0L;
     27     private const ulong KindUtc = 0x4000000000000000L;
     28     private const ulong LocalMask = 9223372036854775808L;
     29     private const long MaxMillis = 0x11efae44cb400L;
     30     internal const long MaxTicks = 0x2bca2875f4373fffL;
     31     [__DynamicallyInvokable]
     32     public static readonly DateTime MaxValue;
     33     private const int MillisPerDay = 0x5265c00;
     34     private const int MillisPerHour = 0x36ee80;
     35     private const int MillisPerMinute = 0xea60;
     36     private const int MillisPerSecond = 0x3e8;
     37     internal const long MinTicks = 0L;
     38     [__DynamicallyInvokable]
     39     public static readonly DateTime MinValue;
     40     private const double OADateMaxAsDouble = 2958466.0;
     41     private const double OADateMinAsDouble = -657435.0;
     42     private const long OADateMinAsTicks = 0x6efdddaec64000L;
     43     private const long TicksCeiling = 0x4000000000000000L;
     44     private const string TicksField = "ticks";
     45     private const ulong TicksMask = 0x3fffffffffffffffL;
     46     private const long TicksPerDay = 0xc92a69c000L;
     47     private const long TicksPerHour = 0x861c46800L;
     48     private const long TicksPerMillisecond = 0x2710L;
     49     private const long TicksPerMinute = 0x23c34600L;
     50     private const long TicksPerSecond = 0x989680L;
     51 
     52     // Methods
     53     static DateTime();
     54     [__DynamicallyInvokable]
     55     public DateTime(long ticks);
     56     [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
     57     private DateTime(ulong dateData);
     58     [__DynamicallyInvokable]
     59     public DateTime(long ticks, DateTimeKind kind);
     60     private DateTime(SerializationInfo info, StreamingContext context);
     61     [__DynamicallyInvokable]
     62     public DateTime(int year, int month, int day);
     63     internal DateTime(long ticks, DateTimeKind kind, bool isAmbiguousDst);
     64     [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
     65     public DateTime(int year, int month, int day, Calendar calendar);
     66     [__DynamicallyInvokable]
     67     public DateTime(int year, int month, int day, int hour, int minute, int second);
     68     [__DynamicallyInvokable]
     69     public DateTime(int year, int month, int day, int hour, int minute, int second, DateTimeKind kind);
     70     public DateTime(int year, int month, int day, int hour, int minute, int second, Calendar calendar);
     71     [__DynamicallyInvokable]
     72     public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond);
     73     [__DynamicallyInvokable]
     74     public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, DateTimeKind kind);
     75     public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, Calendar calendar);
     76     public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, Calendar calendar, DateTimeKind kind);
     77     [__DynamicallyInvokable]
     78     public DateTime Add(TimeSpan value);
     79     private DateTime Add(double value, int scale);
     80     [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
     81     public DateTime AddDays(double value);
     82     [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
     83     public DateTime AddHours(double value);
     84     [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
     85     public DateTime AddMilliseconds(double value);
     86     [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
     87     public DateTime AddMinutes(double value);
     88     [__DynamicallyInvokable]
     89     public DateTime AddMonths(int months);
     90     [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
     91     public DateTime AddSeconds(double value);
     92     [__DynamicallyInvokable]
     93     public DateTime AddTicks(long value);
     94     [__DynamicallyInvokable]
     95     public DateTime AddYears(int value);
     96     [__DynamicallyInvokable]
     97     public static int Compare(DateTime t1, DateTime t2);
     98     [__DynamicallyInvokable]
     99     public int CompareTo(DateTime value);
    100     public int CompareTo(object value);
    101     private static long DateToTicks(int year, int month, int day);
    102     [__DynamicallyInvokable]
    103     public static int DaysInMonth(int year, int month);
    104     internal static long DoubleDateToTicks(double value);
    105     [return: MarshalAs(UnmanagedType.Bool)]
    106     [SecurityCritical, SuppressUnmanagedCodeSecurity, DllImport("QCall", CharSet=CharSet.Unicode)]
    107     internal static extern bool EnableAmPmParseAdjustment();
    108     [__DynamicallyInvokable]
    109     public bool Equals(DateTime value);
    110     [__DynamicallyInvokable]
    111     public override bool Equals(object value);
    112     [__DynamicallyInvokable]
    113     public static bool Equals(DateTime t1, DateTime t2);
    114     [__DynamicallyInvokable]
    115     public static DateTime FromBinary(long dateData);
    116     internal static DateTime FromBinaryRaw(long dateData);
    117     [__DynamicallyInvokable]
    118     public static DateTime FromFileTime(long fileTime);
    119     [__DynamicallyInvokable]
    120     public static DateTime FromFileTimeUtc(long fileTime);
    121     [__DynamicallyInvokable]
    122     public static DateTime FromOADate(double d);
    123     private int GetDatePart(int part);
    124     [__DynamicallyInvokable]
    125     public string[] GetDateTimeFormats();
    126     [__DynamicallyInvokable]
    127     public string[] GetDateTimeFormats(char format);
    128     [__DynamicallyInvokable]
    129     public string[] GetDateTimeFormats(IFormatProvider provider);
    130     [__DynamicallyInvokable]
    131     public string[] GetDateTimeFormats(char format, IFormatProvider provider);
    132     [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable]
    133     public override int GetHashCode();
    134     [MethodImpl(MethodImplOptions.InternalCall), SecurityCritical]
    135     internal static extern long GetSystemTimeAsFileTime();
    136     [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
    137     public TypeCode GetTypeCode();
    138     internal bool IsAmbiguousDaylightSavingTime();
    139     [__DynamicallyInvokable]
    140     public bool IsDaylightSavingTime();
    141     [__DynamicallyInvokable]
    142     public static bool IsLeapYear(int year);
    143     [__DynamicallyInvokable]
    144     public static DateTime operator +(DateTime d, TimeSpan t);
    145     [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable]
    146     public static bool operator ==(DateTime d1, DateTime d2);
    147     [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable]
    148     public static bool operator >(DateTime t1, DateTime t2);
    149     [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable]
    150     public static bool operator >=(DateTime t1, DateTime t2);
    151     [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable]
    152     public static bool operator !=(DateTime d1, DateTime d2);
    153     [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable]
    154     public static bool operator <(DateTime t1, DateTime t2);
    155     [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable]
    156     public static bool operator <=(DateTime t1, DateTime t2);
    157     [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable]
    158     public static TimeSpan operator -(DateTime d1, DateTime d2);
    159     [__DynamicallyInvokable]
    160     public static DateTime operator -(DateTime d, TimeSpan t);
    161     [__DynamicallyInvokable]
    162     public static DateTime Parse(string s);
    163     [__DynamicallyInvokable]
    164     public static DateTime Parse(string s, IFormatProvider provider);
    165     [__DynamicallyInvokable]
    166     public static DateTime Parse(string s, IFormatProvider provider, DateTimeStyles styles);
    167     [__DynamicallyInvokable]
    168     public static DateTime ParseExact(string s, string format, IFormatProvider provider);
    169     [__DynamicallyInvokable]
    170     public static DateTime ParseExact(string s, string format, IFormatProvider provider, DateTimeStyles style);
    171     [__DynamicallyInvokable]
    172     public static DateTime ParseExact(string s, string[] formats, IFormatProvider provider, DateTimeStyles style);
    173     [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable]
    174     public static DateTime SpecifyKind(DateTime value, DateTimeKind kind);
    175     [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable]
    176     public TimeSpan Subtract(DateTime value);
    177     [__DynamicallyInvokable]
    178     public DateTime Subtract(TimeSpan value);
    179     bool IConvertible.ToBoolean(IFormatProvider provider);
    180     byte IConvertible.ToByte(IFormatProvider provider);
    181     char IConvertible.ToChar(IFormatProvider provider);
    182     [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
    183     DateTime IConvertible.ToDateTime(IFormatProvider provider);
    184     decimal IConvertible.ToDecimal(IFormatProvider provider);
    185     double IConvertible.ToDouble(IFormatProvider provider);
    186     short IConvertible.ToInt16(IFormatProvider provider);
    187     int IConvertible.ToInt32(IFormatProvider provider);
    188     long IConvertible.ToInt64(IFormatProvider provider);
    189     sbyte IConvertible.ToSByte(IFormatProvider provider);
    190     float IConvertible.ToSingle(IFormatProvider provider);
    191     object IConvertible.ToType(Type type, IFormatProvider provider);
    192     ushort IConvertible.ToUInt16(IFormatProvider provider);
    193     uint IConvertible.ToUInt32(IFormatProvider provider);
    194     ulong IConvertible.ToUInt64(IFormatProvider provider);
    195     [SecurityCritical]
    196     void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context);
    197     private static double TicksToOADate(long value);
    198     private static long TimeToTicks(int hour, int minute, int second);
    199     [__DynamicallyInvokable]
    200     public long ToBinary();
    201     [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
    202     internal long ToBinaryRaw();
    203     [__DynamicallyInvokable]
    204     public long ToFileTime();
    205     [__DynamicallyInvokable]
    206     public long ToFileTimeUtc();
    207     [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
    208     public DateTime ToLocalTime();
    209     internal DateTime ToLocalTime(bool throwOnOverflow);
    210     public string ToLongDateString();
    211     public string ToLongTimeString();
    212     [__DynamicallyInvokable]
    213     public double ToOADate();
    214     public string ToShortDateString();
    215     public string ToShortTimeString();
    216     [__DynamicallyInvokable]
    217     public override string ToString();
    218     [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable]
    219     public string ToString(IFormatProvider provider);
    220     [__DynamicallyInvokable]
    221     public string ToString(string format);
    222     [__DynamicallyInvokable]
    223     public string ToString(string format, IFormatProvider provider);
    224     [__DynamicallyInvokable]
    225     public DateTime ToUniversalTime();
    226     internal static bool TryCreate(int year, int month, int day, int hour, int minute, int second, int millisecond, out DateTime result);
    227     [__DynamicallyInvokable]
    228     public static bool TryParse(string s, out DateTime result);
    229     [__DynamicallyInvokable]
    230     public static bool TryParse(string s, IFormatProvider provider, DateTimeStyles styles, out DateTime result);
    231     [__DynamicallyInvokable]
    232     public static bool TryParseExact(string s, string format, IFormatProvider provider, DateTimeStyles style, out DateTime result);
    233     [__DynamicallyInvokable]
    234     public static bool TryParseExact(string s, string[] formats, IFormatProvider provider, DateTimeStyles style, out DateTime result);
    235 
    236     // Properties
    237     [__DynamicallyInvokable]
    238     public DateTime Date { [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable] get; }
    239     [__DynamicallyInvokable]
    240     public int Day { [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get; }
    241     [__DynamicallyInvokable]
    242     public DayOfWeek DayOfWeek { [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable] get; }
    243     [__DynamicallyInvokable]
    244     public int DayOfYear { [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get; }
    245     [__DynamicallyInvokable]
    246     public int Hour { [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable] get; }
    247     private ulong InternalKind { [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] get; }
    248     internal long InternalTicks { [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] get; }
    249     [__DynamicallyInvokable]
    250     public DateTimeKind Kind { [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable] get; }
    251     [__DynamicallyInvokable]
    252     public int Millisecond { [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable] get; }
    253     [__DynamicallyInvokable]
    254     public int Minute { [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable] get; }
    255     [__DynamicallyInvokable]
    256     public int Month { [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get; }
    257     [__DynamicallyInvokable]
    258     public static DateTime Now { [__DynamicallyInvokable] get; }
    259     [__DynamicallyInvokable]
    260     public int Second { [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable] get; }
    261     [__DynamicallyInvokable]
    262     public long Ticks { [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get; }
    263     [__DynamicallyInvokable]
    264     public TimeSpan TimeOfDay { [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable] get; }
    265     [__DynamicallyInvokable]
    266     public static DateTime Today { [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable] get; }
    267     [__DynamicallyInvokable]
    268     public static DateTime UtcNow { [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), SecuritySafeCritical, __DynamicallyInvokable] get; }
    269     [__DynamicallyInvokable]
    270     public int Year { [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get; }
    271 }
    272 
    273  
    274 
    275  

    二、了解DateTime结构体

    转到DateTime的定义,也可以看到DateTime确实是struct类型,

     

    看来前面的试验都是无用功了,但DateTime到底是怎样的结构体呢,主要有如下成员

     

    这些成员里面最关键的是Ticks

    Ticks的时间值以 100 毫微秒为单位,它的64位中,前两位表示Kind,后面62位表示有多少个毫微秒。Kind用来指示 DateTime 结构是表示本地时间、协调通用时间 (UTC) 还是 UTC 和本地时间都未指定。Kind 字段用于处理本地时间和 UTC 时间之间的转换。

    DateTime的值范围在0001/1/1 00:00:00到9999/12/31 23:59:59之间

    三、DateTime.Now和DateTime.UtcNow是怎么计算出来的

    反编译DateTime.Now如下:

     1 [__DynamicallyInvokable]
     2 public static DateTime Now
     3 {
     4     [__DynamicallyInvokable]
     5     get
     6     {
     7         DateTime utcNow = UtcNow;
     8         bool isAmbiguousLocalDst = false;
     9         long ticks = TimeZoneInfo.GetDateTimeNowUtcOffsetFromUtc(utcNow, out isAmbiguousLocalDst).Ticks;
    10         long num2 = utcNow.Ticks + ticks;
    11         if (num2 > 0x2bca2875f4373fffL)
    12         {
    13             return new DateTime(0x2bca2875f4373fffL, DateTimeKind.Local);
    14         }
    15         if (num2 < 0L)
    16         {
    17             return new DateTime(0L, DateTimeKind.Local);
    18         }
    19         return new DateTime(num2, DateTimeKind.Local, isAmbiguousLocalDst);
    20     }
    21 }
    22  
    23 
    24  

    大致的意思是先获取DateTime.UtcNow,然后转换为本地时间

    再反编译DateTime.UtcNow:

    1 [__DynamicallyInvokable]
    2 public static DateTime UtcNow =>
    3     new DateTime((ulong) ((GetSystemTimeAsFileTime() + 0x701ce1722770000L) | 0x4000000000000000L));
    4  
    5 
    6  

    最后查阅GetSystemTimeAsFileTime()是Windows的API,作用便是获取当前的UTC时间

  • 相关阅读:
    三元表达式、列表推导式、生成器表达式、递归、匿名函数、内置函数
    迭代器、生成器、面向过程编程
    wxpython 开发sheet
    演示生命周期和重定向
    wxpython 给框架增加菜单栏,工具栏和状态栏
    wxpython 开发俄罗斯方块
    关于重构代码的一些想法
    python 基于GUI 获取鼠标位置
    转载一篇文章 python程序在安卓手机上使用
    wxpython开发一个小游戏(一)
  • 原文地址:https://www.cnblogs.com/yanglang/p/6704111.html
Copyright © 2020-2023  润新知