时间戳(UnixTimestamp)与 《2038年问题》

时间戳是从格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。

现在时间戳的长度是十位(1435113975--2015/6/24 10:46:15)。

要到 2286/11/21 01:46:40 才会变成11位(10000000000),距离现在还有 271年。

 

不同时区获取的时间不一样,生成的时间戳会不一样,比如中国是东八区(+8),美国东部是西五区(-5),两地的时差是13小时,北京比纽约要早13个小时;

一般从中国的12月15日乘飞机去美国, 到达时间就是美国的12月15日,在中国是12月16日。

这样就导致跨时区验证时间戳会不准的情况。

 

所以要把日期协调成世界时间。

C#中 DateTime.ToUniversalTime 方法会把本地时间协调成世界时间。

测试代码:

 

string date = DateTime.Now.ToString();//本地时间
string dateAmerica = DateTime.Now.AddHours(-13).ToString();//模拟美国东部时间
object back = (DateTime.Parse(date).ToUniversalTime().Ticks - 621355968000000000) / 10000000;//协调全球时间的时间戳
object back2 = (DateTime.Parse(date).Ticks - 621355968000000000) / 10000000;//不协调全球时间的时间戳
object backA = (DateTime.Parse(dateAmerica).Ticks - 621355968000000000) / 10000000;//模拟美国东部时间的时间戳
Console.WriteLine("时间:" + date);
Console.WriteLine("协调全球时间的时间戳:" + back);
Console.WriteLine("时间戳的类型:" + back.GetType());
Console.WriteLine("时间戳的长度:" + back.ToString().Length);
Console.WriteLine("不协调全球时间的时间戳:" + back2);
Console.WriteLine("此时美国时间的时间戳:" + backA);

 

为什么要减去621355968000000000?
因为 DateTime.Ticks 表示自 0001 年 1 月 1 日午夜 12:00:00(表示 DateTime.MinValue)以来经过的以 100 纳秒为间隔的间隔数。 它不包括归因于闰秒的嘀嗒数。
其实是减去 0001 年 1 月 1 日午夜 12:00:00 到 1970年01月01日00时00分00秒 之间的秒数

 

输出:

 

《2038年问题》

在计算机应用上,2038年问题可能会导致某些软件在2038年无法正常工作。所有使用UNIX时 间表示时间的程序都将受其影响,因为它们以自1970年1月1日经过的秒数(忽略闰秒)来表示时间。这种时间表示法在类Unix(Unix-like)操 作系统上是一个标准,并会影响以其C编程语言开发给其他大部份操作系统使用的软件。在大部份的32位操作系统上,此“time_t”数据模式使用一个有正 负号的32位元整数(signedint32)存储计算的秒数。依照此“time_t”标准,在此格式能被表示的最后时间是2038年1月19日 03:14:07,星期二(UTC)。超过此一瞬间,时间将会被掩盖(wrap around)且在内部被表示为一个负数,并造成程序无法工作,因为它们无法将此时间识别为2038年,而可能会依个别实作而跳回1970年或1901 年。错误的计算及动作可能因此产生。

 

其实就是在32位系统上,长度溢出导致的异常。

 

posted @ 2015-06-24 11:14  南风叶  阅读(27240)  评论(2编辑  收藏  举报