如何计算DateTime.UtcNow值?

时间:2014-12-05 09:09:38

标签: c# .net windows time timer

.Net究竟从哪里获取此值?这是GetSystemTimeAsFileTime的值吗? 如何计算这个值呢?它是以某种方式基于QPC值吗?

3 个答案:

答案 0 :(得分:4)

UtcNow定义如下。(为简洁而剥离的属性)

public static DateTime UtcNow
{
    get
    {
        return new DateTime((ulong) ((GetSystemTimeAsFileTime() + 0x701ce1722770000L) | 0x4000000000000000L));
    }
}

GetSystemTimeAsFileTime被定义为内部呼叫。

[MethodImpl(MethodImplOptions.InternalCall), SecurityCritical]
internal static extern long GetSystemTimeAsFileTime();

Reflector再也无法帮助了,让我们深入了解sscli

GetSystemTimeAsFileTime映射到SystemNative::__GetSystemTimeAsFileTime(ecall.cpp)

FCFuncStart(gDateTimeFuncs)
    FCFuncElement("GetSystemTimeAsFileTime", SystemNative::__GetSystemTimeAsFileTime)
FCFuncEnd()

最后SystemNative::__GetSystemTimeAsFileTime实现如下(comsystem.cpp)

FCIMPL0(INT64, SystemNative::__GetSystemTimeAsFileTime)
{
    WRAPPER_CONTRACT;
    STATIC_CONTRACT_SO_TOLERANT;

    INT64 timestamp;

    ::GetSystemTimeAsFileTime((FILETIME*)&timestamp);

#if BIGENDIAN
    timestamp = (INT64)(((UINT64)timestamp >> 32) | ((UINT64)timestamp << 32));
#endif

    return timestamp;
}
FCIMPLEND;

因此,UtcNow只是GetSystemTimeAsFileTime函数的包装器,并处理BigEndian的大小写。

在微软发布其开源操作系统之前,我们无法继续前进:)

答案 1 :(得分:1)

DateTime.UtcNow的计算方法是从当前日期/时间减去主机操作系统时区的偏移量。

是的,在内部查看ILSpy,它正在调用GetSystemTimeAsFileTime

[SecurityCritical]
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern long GetSystemTimeAsFileTime();

要手动使用TimeZoneInfo.Local拉出当前时区,这会为您提供BaseUtcOffset,然后您可以从当前日期/时间中减去,例如:

TimeZoneInfo tz_info = TimeZoneInfo.Local;
TimeSpan offset = tz_info.BaseUtcOffset;
DateTime now = DateTime.Now;
DateTime utc_now = now.Subtract(offset);

请注意,这些值将作为操作系统设置存储在注册表中以及更高版本中。请记住,当您安装Windows时,您可以选择您想要的时区。如果您有勇气,可以在此处找到一些信息:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones

在MSDN博客上有一篇关于时区等的优秀文章 - http://blogs.msdn.com/b/bclteam/archive/2007/06/07/exploring-windows-time-zones-with-system-timezoneinfo-josh-free.aspx

答案 2 :(得分:0)

Whow。人们检查IL而不是源代码。

DateTime类的源位于http://referencesource.microsoft.com/#mscorlib/system/datetime.cs,df6b1eba7461813b

UtcNow从第959行开始。

无需使用反汇编程序,反射器或其他任何东西 - 您可以看到编写的代码。