UTC是什么
UTC表示协调世界时,英:Coordinated Universal Time ,法:Temps Universel Coordonné,
又称世界统一时间,世界标准时间,国际协调时间。英文(CUT)和法文(TUC)的缩写不同,作为妥协,简称UTC。
协调世界时是以原子时秒长为基础,在时刻上尽量接近于世界时的一种时间计量系统。
UTC是经过平均太阳时(以格林威治时间GMT为准)、地轴运动修正后的新时标以及以「秒」为单位的国际原子时所综合精算而成的时间,
计算过程相当严谨精密,因此若以「世界标准时间」的角度来说,UTC比GMT来得更加精准。
其误差值必须保持在0.9秒以内,若大于0.9秒则由位于巴黎的国际地球自转事务中央局发布闰秒,
使UTC与地球自转周期一致。所以基本上UTC的本质强调的是比GMT更为精确的世界时间标准。
Unix时间戳
Unix时间戳(英文为Unix epoch, Unix time, POSIX time 或 Unix timestamp)
是从1970年1月1日(UTC/GMT的午夜)开始所经过的秒数,不考虑闰秒。
UNIX时间戳的0按照ISO 8601规范为 :1970-01-01T00:00:00Z
.
一个小时表示为UNIX时间戳格式为:3600秒;一天表示为UNIX时间戳为86400秒,闰秒不计算。
因此我们可以看到,Unix时间戳其实是人为选取了UTC时间中的某个时刻并将这个时刻作为起点开始累计秒数,从而计时。
在大多数的UNIX系统中UNIX时间戳存储为32位,这样会引发2038年问题或Y2038。
最初计算机操作系统是32位,而时间也是用32位表示。1年365天的总秒数是 31536000,2147483647/31536000 = 68.1,
也就是说32位能表示的最长时间是68年,从1970年开始的话,
加上68.1,实际最终到2038年01月19日03时14分07秒,便会到达最大时间,过了这个时间点,
所有32位操作系统时间便会变为10000000 00000000 00000000 00000000,
算下来也就是1901年12月13日20时45分52秒,这样便会出现时间回归的现象,很多软件便会运行异常了。
因为用32位来表示时间的最大间隔是68年,
而最早出现的UNIX操作系统考虑到计算机产生的年代和应用的时限综合取了1970年1月1日作为UNIX TIME的纪元时间(开始时间),
至于时间回归的现象相信随着64为操作系统的产生逐渐得到解决,
因为用64位操作系统可以表示到 292,277,026,596年12月4日15时30分08秒,
相信我们的N代子孙,哪怕地球毁灭那天都不用愁不够用了,因为这个时间已经是千亿年以后了。
C#中的时间
1.获取当前时间
在C#中可以通过DateTime
类获取当前时间,如下代码:
DateTime time1 = DateTime.Now;
DateTime time2 = DateTime.UtcNow;
label1.Text = "DateTime.Now:" + time1.ToString() + "\n";
label1.Text += "DateTime.UtcNow:" + time2.ToString();
可以获取两种时间,一种是本地当前时间,一种是UTC的当前时间。例如北京时间是东八区,相对于UTC时间而言加了8个小时。
因此获取到的Now是比UtcNow多8个小时的。
运行结果如下:
2.格式化时间
对于时间的输出,我们直接可以利用DateTime自带的ToString()
函数完成,并且支持自定义格式。
自定义格式的日期格式如下,可根据需要进行自由搭配:
Unix时间戳与日期相互转换
1.Unix时间戳转日期
public String Unix2Time(double stamp)
{
DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1, 0, 0, 0));
startTime = startTime.AddSeconds(stamp);
return startTime.ToString("yyyy-MM-dd HH:mm:ss.fff");
}
2.日期转Unix时间戳
public double Time2Unix(string date)
{
double result = 0;
DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1, 0, 0, 0));
DateTime now = DateTime.Parse(date);
result = (now - startTime).TotalSeconds;
return result;
}
运行结果如下: 对应按钮点击事件代码如下:
DateTime time1 = DateTime.Now;
DateTime time2 = DateTime.UtcNow;
label1.Text = "DateTime.Now:" + time1.ToString("yyyy-MM-dd HH:mm:ss") + "\n";
label1.Text += "DateTime.UtcNow:" + time2.ToString("yyyy-MM-dd HH:mm:ss") + "\n";
label1.Text += "Unix timestamp:" + Time2Unix(time1.ToString()).ToString() + "\n";
label1.Text += "Datetime:" + Unix2Time(Time2Unix(time1.ToString()));
自定义时间起点
有时为了数据的存储和数据量的大小,其实我们完全可以自定义一个时间累积系统,设置时间的起点。
例如知道应用的时间范围不会超过Int16范围,那么就可以利用Int16类型存储,不再需要Int32。可以减少一半的存储量。
要想这样只需要把代码中的1970,1,1,0,0,0
改成
你想要的时间起点即可,如2017,4,20,0,0,0
。
可以看到,程序可以正确按照我们自定义的起点解析出时间。
最后推荐一个在线Unix时间戳转换工具,点击进入。
本文作者原创,未经许可不得转载,谢谢配合