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时间

原文地址:https://www.cnblogs.com/yanglang/p/6704111.html