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

二、了解DateTime结构体

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

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

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

 [Serializable, __DynamicallyInvokable]
public struct DateTime : IComparable, IFormattable, IConvertible, ISerializable, IComparable<DateTime>, IEquatable<DateTime>
{
// Fields
private ulong dateData;
private const string DateDataField = "dateData";
private const int DatePartDay = ;
private const int DatePartDayOfYear = ;
private const int DatePartMonth = ;
private const int DatePartYear = ;
private const int DaysPer100Years = 0x8eac;
private const int DaysPer400Years = 0x23ab1;
private const int DaysPer4Years = 0x5b5;
private const int DaysPerYear = 0x16d;
private const int DaysTo10000 = 0x37b9db;
private const int DaysTo1601 = 0x8eac4;
private const int DaysTo1899 = 0xa9559;
private static readonly int[] DaysToMonth365;
private static readonly int[] DaysToMonth366;
private const long DoubleDateOffset = 0x85103c0cb83c000L;
private const long FileTimeOffset = 0x701ce1722770000L;
private const ulong FlagsMask = 13835058055282163712L;
private const ulong KindLocal = 9223372036854775808L;
private const ulong KindLocalAmbiguousDst = 13835058055282163712L;
private const int KindShift = 0x3e;
private const ulong KindUnspecified = 0L;
private const ulong KindUtc = 0x4000000000000000L;
private const ulong LocalMask = 9223372036854775808L;
private const long MaxMillis = 0x11efae44cb400L;
internal const long MaxTicks = 0x2bca2875f4373fffL;
[__DynamicallyInvokable]
public static readonly DateTime MaxValue;
private const int MillisPerDay = 0x5265c00;
private const int MillisPerHour = 0x36ee80;
private const int MillisPerMinute = 0xea60;
private const int MillisPerSecond = 0x3e8;
internal const long MinTicks = 0L;
[__DynamicallyInvokable]
public static readonly DateTime MinValue;
private const double OADateMaxAsDouble = 2958466.0;
private const double OADateMinAsDouble = -657435.0;
private const long OADateMinAsTicks = 0x6efdddaec64000L;
private const long TicksCeiling = 0x4000000000000000L;
private const string TicksField = "ticks";
private const ulong TicksMask = 0x3fffffffffffffffL;
private const long TicksPerDay = 0xc92a69c000L;
private const long TicksPerHour = 0x861c46800L;
private const long TicksPerMillisecond = 0x2710L;
private const long TicksPerMinute = 0x23c34600L;
private const long TicksPerSecond = 0x989680L; // Methods
static DateTime();
[__DynamicallyInvokable]
public DateTime(long ticks);
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
private DateTime(ulong dateData);
[__DynamicallyInvokable]
public DateTime(long ticks, DateTimeKind kind);
private DateTime(SerializationInfo info, StreamingContext context);
[__DynamicallyInvokable]
public DateTime(int year, int month, int day);
internal DateTime(long ticks, DateTimeKind kind, bool isAmbiguousDst);
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
public DateTime(int year, int month, int day, Calendar calendar);
[__DynamicallyInvokable]
public DateTime(int year, int month, int day, int hour, int minute, int second);
[__DynamicallyInvokable]
public DateTime(int year, int month, int day, int hour, int minute, int second, DateTimeKind kind);
public DateTime(int year, int month, int day, int hour, int minute, int second, Calendar calendar);
[__DynamicallyInvokable]
public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond);
[__DynamicallyInvokable]
public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, DateTimeKind kind);
public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, Calendar calendar);
public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, Calendar calendar, DateTimeKind kind);
[__DynamicallyInvokable]
public DateTime Add(TimeSpan value);
private DateTime Add(double value, int scale);
[__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
public DateTime AddDays(double value);
[__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
public DateTime AddHours(double value);
[__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
public DateTime AddMilliseconds(double value);
[__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
public DateTime AddMinutes(double value);
[__DynamicallyInvokable]
public DateTime AddMonths(int months);
[__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
public DateTime AddSeconds(double value);
[__DynamicallyInvokable]
public DateTime AddTicks(long value);
[__DynamicallyInvokable]
public DateTime AddYears(int value);
[__DynamicallyInvokable]
public static int Compare(DateTime t1, DateTime t2);
[__DynamicallyInvokable]
public int CompareTo(DateTime value);
public int CompareTo(object value);
private static long DateToTicks(int year, int month, int day);
[__DynamicallyInvokable]
public static int DaysInMonth(int year, int month);
internal static long DoubleDateToTicks(double value);
[return: MarshalAs(UnmanagedType.Bool)]
[SecurityCritical, SuppressUnmanagedCodeSecurity, DllImport("QCall", CharSet=CharSet.Unicode)]
internal static extern bool EnableAmPmParseAdjustment();
[__DynamicallyInvokable]
public bool Equals(DateTime value);
[__DynamicallyInvokable]
public override bool Equals(object value);
[__DynamicallyInvokable]
public static bool Equals(DateTime t1, DateTime t2);
[__DynamicallyInvokable]
public static DateTime FromBinary(long dateData);
internal static DateTime FromBinaryRaw(long dateData);
[__DynamicallyInvokable]
public static DateTime FromFileTime(long fileTime);
[__DynamicallyInvokable]
public static DateTime FromFileTimeUtc(long fileTime);
[__DynamicallyInvokable]
public static DateTime FromOADate(double d);
private int GetDatePart(int part);
[__DynamicallyInvokable]
public string[] GetDateTimeFormats();
[__DynamicallyInvokable]
public string[] GetDateTimeFormats(char format);
[__DynamicallyInvokable]
public string[] GetDateTimeFormats(IFormatProvider provider);
[__DynamicallyInvokable]
public string[] GetDateTimeFormats(char format, IFormatProvider provider);
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable]
public override int GetHashCode();
[MethodImpl(MethodImplOptions.InternalCall), SecurityCritical]
internal static extern long GetSystemTimeAsFileTime();
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
public TypeCode GetTypeCode();
internal bool IsAmbiguousDaylightSavingTime();
[__DynamicallyInvokable]
public bool IsDaylightSavingTime();
[__DynamicallyInvokable]
public static bool IsLeapYear(int year);
[__DynamicallyInvokable]
public static DateTime operator +(DateTime d, TimeSpan t);
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable]
public static bool operator ==(DateTime d1, DateTime d2);
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable]
public static bool operator >(DateTime t1, DateTime t2);
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable]
public static bool operator >=(DateTime t1, DateTime t2);
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable]
public static bool operator !=(DateTime d1, DateTime d2);
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable]
public static bool operator <(DateTime t1, DateTime t2);
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable]
public static bool operator <=(DateTime t1, DateTime t2);
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable]
public static TimeSpan operator -(DateTime d1, DateTime d2);
[__DynamicallyInvokable]
public static DateTime operator -(DateTime d, TimeSpan t);
[__DynamicallyInvokable]
public static DateTime Parse(string s);
[__DynamicallyInvokable]
public static DateTime Parse(string s, IFormatProvider provider);
[__DynamicallyInvokable]
public static DateTime Parse(string s, IFormatProvider provider, DateTimeStyles styles);
[__DynamicallyInvokable]
public static DateTime ParseExact(string s, string format, IFormatProvider provider);
[__DynamicallyInvokable]
public static DateTime ParseExact(string s, string format, IFormatProvider provider, DateTimeStyles style);
[__DynamicallyInvokable]
public static DateTime ParseExact(string s, string[] formats, IFormatProvider provider, DateTimeStyles style);
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable]
public static DateTime SpecifyKind(DateTime value, DateTimeKind kind);
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable]
public TimeSpan Subtract(DateTime value);
[__DynamicallyInvokable]
public DateTime Subtract(TimeSpan value);
bool IConvertible.ToBoolean(IFormatProvider provider);
byte IConvertible.ToByte(IFormatProvider provider);
char IConvertible.ToChar(IFormatProvider provider);
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
DateTime IConvertible.ToDateTime(IFormatProvider provider);
decimal IConvertible.ToDecimal(IFormatProvider provider);
double IConvertible.ToDouble(IFormatProvider provider);
short IConvertible.ToInt16(IFormatProvider provider);
int IConvertible.ToInt32(IFormatProvider provider);
long IConvertible.ToInt64(IFormatProvider provider);
sbyte IConvertible.ToSByte(IFormatProvider provider);
float IConvertible.ToSingle(IFormatProvider provider);
object IConvertible.ToType(Type type, IFormatProvider provider);
ushort IConvertible.ToUInt16(IFormatProvider provider);
uint IConvertible.ToUInt32(IFormatProvider provider);
ulong IConvertible.ToUInt64(IFormatProvider provider);
[SecurityCritical]
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context);
private static double TicksToOADate(long value);
private static long TimeToTicks(int hour, int minute, int second);
[__DynamicallyInvokable]
public long ToBinary();
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
internal long ToBinaryRaw();
[__DynamicallyInvokable]
public long ToFileTime();
[__DynamicallyInvokable]
public long ToFileTimeUtc();
[__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
public DateTime ToLocalTime();
internal DateTime ToLocalTime(bool throwOnOverflow);
public string ToLongDateString();
public string ToLongTimeString();
[__DynamicallyInvokable]
public double ToOADate();
public string ToShortDateString();
public string ToShortTimeString();
[__DynamicallyInvokable]
public override string ToString();
[TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable]
public string ToString(IFormatProvider provider);
[__DynamicallyInvokable]
public string ToString(string format);
[__DynamicallyInvokable]
public string ToString(string format, IFormatProvider provider);
[__DynamicallyInvokable]
public DateTime ToUniversalTime();
internal static bool TryCreate(int year, int month, int day, int hour, int minute, int second, int millisecond, out DateTime result);
[__DynamicallyInvokable]
public static bool TryParse(string s, out DateTime result);
[__DynamicallyInvokable]
public static bool TryParse(string s, IFormatProvider provider, DateTimeStyles styles, out DateTime result);
[__DynamicallyInvokable]
public static bool TryParseExact(string s, string format, IFormatProvider provider, DateTimeStyles style, out DateTime result);
[__DynamicallyInvokable]
public static bool TryParseExact(string s, string[] formats, IFormatProvider provider, DateTimeStyles style, out DateTime result); // Properties
[__DynamicallyInvokable]
public DateTime Date { [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable] get; }
[__DynamicallyInvokable]
public int Day { [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get; }
[__DynamicallyInvokable]
public DayOfWeek DayOfWeek { [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable] get; }
[__DynamicallyInvokable]
public int DayOfYear { [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get; }
[__DynamicallyInvokable]
public int Hour { [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable] get; }
private ulong InternalKind { [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] get; }
internal long InternalTicks { [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] get; }
[__DynamicallyInvokable]
public DateTimeKind Kind { [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable] get; }
[__DynamicallyInvokable]
public int Millisecond { [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable] get; }
[__DynamicallyInvokable]
public int Minute { [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable] get; }
[__DynamicallyInvokable]
public int Month { [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get; }
[__DynamicallyInvokable]
public static DateTime Now { [__DynamicallyInvokable] get; }
[__DynamicallyInvokable]
public int Second { [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable] get; }
[__DynamicallyInvokable]
public long Ticks { [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get; }
[__DynamicallyInvokable]
public TimeSpan TimeOfDay { [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable] get; }
[__DynamicallyInvokable]
public static DateTime Today { [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable] get; }
[__DynamicallyInvokable]
public static DateTime UtcNow { [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), SecuritySafeCritical, __DynamicallyInvokable] get; }
[__DynamicallyInvokable]
public int Year { [__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get; }
}

二、了解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如下:

 [__DynamicallyInvokable]
public static DateTime Now
{
[__DynamicallyInvokable]
get
{
DateTime utcNow = UtcNow;
bool isAmbiguousLocalDst = false;
long ticks = TimeZoneInfo.GetDateTimeNowUtcOffsetFromUtc(utcNow, out isAmbiguousLocalDst).Ticks;
long num2 = utcNow.Ticks + ticks;
if (num2 > 0x2bca2875f4373fffL)
{
return new DateTime(0x2bca2875f4373fffL, DateTimeKind.Local);
}
if (num2 < 0L)
{
return new DateTime(0L, DateTimeKind.Local);
}
return new DateTime(num2, DateTimeKind.Local, isAmbiguousLocalDst);
}
}

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

再反编译DateTime.UtcNow:

 [__DynamicallyInvokable]
public static DateTime UtcNow =>
new DateTime((ulong) ((GetSystemTimeAsFileTime() + 0x701ce1722770000L) | 0x4000000000000000L));

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

C#中的DateTime的更多相关文章

  1. sql语句中获取datetime的日期部分或时间部分

    sql语句中获取datetime的日期部分 sql语句中 经常操作操作datetime类型数据.今天在写一个存储过程的时候需要将 一个datetime的值的 日期部分提取出来.网上有许多这方面的介绍. ...

  2. Dynamics AX 2012 R2 在AIF服务契约中使用DateTime

    Reinhard在AIF中使用DateTime作为服务契约的参数,与DotNet程序进行交互时,总是因为时区的问题,导致DotNet提交的System.DateTime与AIF中接收的DateTime ...

  3. MySQL中的datetime与timestamp比较-------转载

    原文地址http://database.51cto.com/art/200905/124240.htm MySQL中的datetime与timestamp比较 本文将通过实例比较MySQL中的date ...

  4. sql语句中获取datetime任何部分

    sql语句中获取datetime的日期部分 sql语句中 经常操作操作datetime类型数据.今天在写一个存储过程的时候需要将 一个datetime的值的 日期部分提取出来.网上有许多这方面的介绍. ...

  5. SQL server数据库中的DateTime类型出现的问题

    我们知道这个SQL server数据库中的DateTime类型是数据库应用开发中经经常使用到的一种数据类型.而C#语言中也有DateTime类型,尽管二者都是用来描写叙述时间的,可是它们的默认值是不同 ...

  6. SQL-27 给出每个员工每年薪水涨幅超过5000的员工编号emp_no、薪水变更开始日期from_date以及薪水涨幅值salary_growth,并按照salary_growth逆序排列。 提示:在sqlite中获取datetime时间对应的年份函数为strftime('%Y', to_date)

    题目描述 给出每个员工每年薪水涨幅超过5000的员工编号emp_no.薪水变更开始日期from_date以及薪水涨幅值salary_growth,并按照salary_growth逆序排列. 提示:在s ...

  7. JS、C#及SQL中的DateTime

    一:SQL中的DataTime 1.       between and 相当于>= and <= 2.       常用的将DataTime查询成字符串的方法 Select CONVER ...

  8. .NET 中的DateTime

    DateTime简介 DateTime是.NET中的时间类型,可以通过DateTime完成诸如获取当前的系统时间等操作.DateTime在.NET中是一个结构体,而并不是一个类. 如上图所示,这个图标 ...

  9. C#中的DateTime:本周第一天,本月第一天,今年第一天,本周第一天的时间

    有时辰需要按照当前时刻,断定其它的都没有什么难度,只是本季度稍稍麻烦些.因为一年有四个季度,可以按照当前月份,获得本季度第一个月的月份,然后这个月的第一天,就是本季度的第一天了 DateTime dt ...

  10. 关于C#中的DateTime类型的技巧

    * datetime.now.tostring()方法默认的你是无法得到全部的时间的格式的,只能得到日期,得不到具体时间,如果要具体时间,就应该使用 datetime的tostring()重载,dat ...

随机推荐

  1. virtualbox - 2台虚拟机之间通过ssh互访

    virtualbox 5.2.12 一台虚拟机是Debian 9,另一台是Ubuntu 18.04. 注意: 2台虚拟机系统里要安装ssh ! sudo apt install ssh 然后在virt ...

  2. 利用shell脚本或者php移动某个文件夹下的文件到各自的日期组成的目录下

    背景是这样的:网站一开始访问量比较小,大家就把所有的图片文件上传到一个目录下(比如是/data/images/).后来访问量大了,图片也多了,这样就影响读取效率.所以有个这样的需求,把这些个图片文件移 ...

  3. Unity报错 GameObject is already being activated or deactivated

    unity 在OnDisable 方法里设置父节点会报这个错. void OnDisable() { // transform.parent = oldParent; transform.SetPar ...

  4. PMS-授权中心

    概述 授权中心用基于角色的访问控制思想(RBAC-Role Based Access Control)来实现各个业务系统的功能权限及数据权限控制.功能权限是指能否进入页面及使用页面上的操作.数据权限控 ...

  5. C#批量插入数据到Sqlserver中的四种方式 - 转

    先创建一个用来测试的数据库和表,为了让插入数据更快,表中主键采用的是GUID,表中没有创建任何索引.GUID必然是比自增长要快的,因为你生成一个GUID算法所花的时间肯定比你从数据表中重新查询上一条记 ...

  6. 【php增删改查实例】第十八节 - login.php编写

    1.对用户名和密码进行非空判断(后台验证) $username; $password; if(isset($_POST['username']) && $_POST['username ...

  7. [HNOI2018]排列[堆]

    题意 给定一棵树,每个点有点权,第 \(i\) 个点被删除的代价为 \(w_{p[i]}\times i\) ,问最小代价是多少. 分析 与国王游戏一题类似. 容易发现权值最小的点在其父亲选择后就会立 ...

  8. 微信小程序 canvas 绘图问题总结

    业务中碰到微信小程序需要生成海报进行朋友圈分享,这个是非常常见的功能,没想到实际操作的时候花了整整一天一夜才搞好,微信的 canvas 绘图实在是太难用了,官方快点优化一下吧. 业务非常简单,只需要将 ...

  9. C#断点续传下载。

    断点续传 最近在优化之前的下载流程,仅此篇幅留作笔记之用,日后其他研究此类问题的伙伴可以马上了解原理和开发,减少开发成本. 原理:断点续传目前比较通用的是使用HTTP续传方式,相关的资料可以通过访问: ...

  10. Android恶意样本数据集汇总

    硕士论文的研究方向为Android恶意应用分类,因此花了一点时间去搜集Android恶意样本.其中一部分来自过去论文的公开数据集,一部分来自社区或平台的样本.现做一个汇总,标明了样本或数据集的采集时间 ...