好吧,考虑到
在mscorelib上使用ILSpy我们可以发现,DateTime.Now是这样出现的:
public static DateTime Now
{
get
{
DateTime utcNow = DateTime.UtcNow;
bool isAmbiguousDst = false;
long ticks = TimeZoneInfo.GetDateTimeNowUtcOffsetFromUtc(utcNow, out isAmbiguousDst).Ticks;
long num = utcNow.Ticks + ticks;
if (num > 3155378975999999999L)
{
return new DateTime(3155378975999999999L, DateTimeKind.Local);
}
if (num < 0L)
{
return new DateTime(0L, DateTimeKind.Local);
}
return new DateTime(num, DateTimeKind.Local, isAmbiguousDst);
}
}
函数GetDateTimeNowUtcOffsetFromUtc 如下所示:
internal static TimeSpan GetDateTimeNowUtcOffsetFromUtc(DateTime time, out bool isAmbiguousLocalDst)
{
isAmbiguousLocalDst = false;
TimeZoneInfo.OffsetAndRule oneYearLocalFromUtc = TimeZoneInfo.GetOneYearLocalFromUtc(time.Year);
TimeSpan timeSpan = oneYearLocalFromUtc.offset;
if (oneYearLocalFromUtc.rule != null)
{
bool isDaylightSavingsFromUtc = TimeZoneInfo.GetIsDaylightSavingsFromUtc(time, time.Year, oneYearLocalFromUtc.offset, oneYearLocalFromUtc.rule, out isAmbiguousLocalDst);
timeSpan += (isDaylightSavingsFromUtc ? oneYearLocalFromUtc.rule.DaylightDelta : TimeSpan.Zero);
}
return timeSpan;
}
GetOneYearLocalFromUtc 改为:
private static TimeZoneInfo.OffsetAndRule GetOneYearLocalFromUtc(int year)
{
if (TimeZoneInfo.s_oneYearLocalFromUtc == null || TimeZoneInfo.s_oneYearLocalFromUtc.year != year)
{
TimeZoneInfo currentOneYearLocal = TimeZoneInfo.GetCurrentOneYearLocal();
TimeZoneInfo.AdjustmentRule rule = (currentOneYearLocal.m_adjustmentRules == null) ? null : currentOneYearLocal.m_adjustmentRules[0];
TimeZoneInfo.s_oneYearLocalFromUtc = new TimeZoneInfo.OffsetAndRule(year, currentOneYearLocal.BaseUtcOffset, rule);
}
return TimeZoneInfo.s_oneYearLocalFromUtc;
}
最后GetCurrentOneYearLocal 看起来像:
private static TimeZoneInfo GetCurrentOneYearLocal()
{
Win32Native.TimeZoneInformation timeZoneInformation = default(Win32Native.TimeZoneInformation);
long num = (long)UnsafeNativeMethods.GetTimeZoneInformation(out timeZoneInformation);
TimeZoneInfo result;
if (num == -1L)
{
result = TimeZoneInfo.CreateCustomTimeZone("Local", TimeSpan.Zero, "Local", "Local");
}
else
{
result = TimeZoneInfo.GetLocalTimeZoneFromWin32Data(timeZoneInformation, false);
}
return result;
}
有趣的函数是GetTimeZoneInformation,存在于kernel32.dll,文档中描述如下:
检索当前时区设置。这些设置控制
协调世界时 (UTC) 和本地时间之间的转换。
要访问该时间信息,Windows 实际上使用IO 访问。不确定这个是否可以定义为“阻塞”,但它肯定会访问保存在磁盘上的系统信息,至少是其中的一部分。