起因
进行 Http 通信的时候,存在着计算时间戳的需求,Google 一下就能搜到一堆计算时间戳的代码。
var startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
var timeStamp = (long)(DateTime.Now - startTime).TotalSeconds;
当你为通信成功而喜悦的时候,却不知埋下了时间戳验证不通过的祸根。因为当时区切换的时候,存在着时区缓存。
经过
微软对 TimeZone.CurrentTimeZone 的描述中有这样一段话: Local time zone data is cached after CurrentTimeZone is first used to retrieve time zone information. If the system’s local time zone subsequently changes, the CurrentTimeZone property does not reflect this change. If you need to handle time zone changes while your application is running, use the TimeZoneInfo class and call its ClearCachedData() method. 看了这段话,便写了 demo 去验证,结果得到了同样的错误结果。
奇怪,明明清理了时区缓存,为什么还是一样的结果(这里的原因暂时未知,还请知道的大佬指导一下)。为了解决这个奇怪的现象,继续查看官方文档 TimeZone.CurrentTimeZone 发现了这样一段话:The CurrentTimeZone property corresponds to the TimeZoneInfo.Local property. Whenever possible, use the TimeZoneInfo.Local property. 按照建议,写了另外一个 demo 。
这时候的输出就是日思夜想的结果。于是把计算时间戳的代码更改为
TimeZoneInfo.ClearCachedData();
var startTime = new DateTime(1970, 1, 1) + TimeZoneInfo.Local.BaseUtcOffset;
var timeStamp = (long)(DateTime.Now - startTime).TotalSeconds;
至此,问题得到解决。
结论
- 尽量使用 TimeZoneInfo.Local 替换 TimeZone.CurrentTimeZone
- 如果时区切换会影响到你程序的功能,使用 TimeZoneInfo.ClearCachedData() 清除时区缓存。