c#之中表示时间的类型是DateTime,其中并没有直接获取unix时间戳的方法,而是通过Ticks属性进行计算。
Unix时间戳是从1970年1月1日0:0:0开始计算,Ticks则从0001年1月1日开始计算,单位是100纳秒数,所以减去1970年1月1日的Ticks之后还得除以一个非常大的数字,网上搜一下一般会搜到这样的办法:
DateTime t = new DateTime(2018, 12, 26, 0, 0, 0);//需要转为unix时间戳的时间
DateTime dt1970 = new DateTime(1970, 1, 1, 0, 0, 0); //1970年1月1日0:0:0的Ticks纳秒数
long unix_timestamp = (t.Ticks - dt1970.Ticks) / (10000 * 1000); //10000个100纳秒为1毫秒,1000毫秒为1秒,所以需要除以10000 * 1000
当然还有简单粗暴一点的:
DateTime t = new DateTime(2018, 12, 26, 0, 0, 0);//需要转为unix时间戳的时间
long unix_timestamp = (t.Ticks - 621355968000000000) / (10000 * 1000); //直接写上1970年1月1日0:0:0的纳秒数
但是无论是哪个方法,最终得到的结果都是1545782400,在网上找个unix时间戳工具算一下,可以看到,这是2018/12/26 8:0:0
怎么回事?明明写的是2018/12/26 0:0:0,为什么会多出八个小时?
网上所有相关文章之中都没有提到这一点,这是个很大的坑!
其实原因很简单,Datetime的Ticks,以格林尼治时间为准,而我们本地的时间是北京时间,比如本地时间的比如2018/12/26 0:0:0,并不等于格林尼治时间的比如2018/12/26 0:0:0,而是恰好差了八个小时,所以直接做减法得到的答案是正确的,但却不是我们想要的!反而会造成很多问题。
若想获得正常的,北京时间的unix时间戳,请使用如下代码(在1970年的Ticks之前加上一个ToLocalTime()方法):
DateTime t = new DateTime(2018, 12, 26, 0, 0, 0);//需要转为unix时间戳的时间
DateTime dt1970 = new DateTime(1970, 1, 1, 0, 0, 0); //1970年1月1日0:0:0的Ticks纳秒数
long unix_timestamp = (t.Ticks - dt1970.ToLocalTime().Ticks) / (10000 * 1000); //加上ToLocalTime方法,将格林尼治时间1970/1/1转为北京时间