Tags: Others

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()函数完成,并且支持自定义格式。 自定义格式的日期格式如下,可根据需要进行自由搭配:
table1 table1

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时间戳转换工具,点击进入

本文作者原创,未经许可不得转载,谢谢配合

返回顶部