You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

本地时间与UTC时间的Unix时间戳为何一致?DateTime/DateTimeOffset转换异常求助

本地时间与UTC时间的Unix时间戳为何一致?DateTime/DateTimeOffset转换异常求助

兄弟我太懂你现在的困惑了!刚看到本地时间和UTC时间的Unix时间戳居然一模一样的时候,我也愣了好一会儿——这完全不符合直觉啊!别急,我来给你拆解清楚问题出在哪,以及正确的操作姿势。

先搞懂Unix时间戳的本质

首先得明确一个核心知识点:Unix时间戳本身就是以UTC时间为基准,计算从1970年1月1日00:00:00 UTC到当前时刻的秒数。它代表的是时间线上的一个绝对点,不管你用哪个时区的时间来表示这个点,转换出来的时间戳都是同一个值。

举个例子:你在东八区的2023/10/31 23:11:33,和UTC的2023/10/31 15:11:33,本质上是同一个时间点,只是时区不同导致显示的时间字符串不一样,所以对应的Unix时间戳必然相同——这是正常现象,不是你代码写错了!

你的转换代码问题出在哪?

来看你最后那段转回本地时间的代码:

DateTime localDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Local);
localDateTime = localDateTime.AddSeconds(localTimeStamp).ToLocalTime();

这里的问题在于:你把起始时间设成了本地时区的1970年1月1日,但Unix时间戳是基于UTC起始点的。然后你又调用了ToLocalTime(),相当于做了两次时区转换,结果自然就乱了。

正确的转换方式

1. 从时间转Unix时间戳(本来就该一致)

不管你用本地时间还是UTC时间,只要是同一时刻,转出来的时间戳必然相同,这是正确的。如果你真的需要把本地时间“当成UTC时间”来生成时间戳(很少有这种需求,但万一你要),可以这么写:

// 不推荐,仅特殊场景用:把本地时间当作UTC时间生成时间戳
long wrongLocalAsUtcStamp = new DateTimeOffset(localNow.Year, localNow.Month, localNow.Day, localNow.Hour, localNow.Minute, localNow.Second, TimeSpan.Zero).ToUnixTimeSeconds();

2. 从Unix时间戳转回本地时间

这才是你需要修正的地方,推荐三种靠谱的写法:

long timestamp = 1698765093;

// 方法1:用DateTimeOffset最直观(推荐)
DateTime localFromOffset = DateTimeOffset.FromUnixTimeSeconds(timestamp).LocalDateTime;
Console.WriteLine("转换结果(DateTimeOffset):" + localFromOffset.ToString("yyyy/MM/dd HH:mm:ss"));

// 方法2:用DateTime.UnixEpoch(.NET Core 2.1及以上支持)
DateTime localFromUnixEpoch = DateTime.UnixEpoch.AddSeconds(timestamp).ToLocalTime();
Console.WriteLine("转换结果(UnixEpoch):" + localFromUnixEpoch.ToString("yyyy/MM/dd HH:mm:ss"));

// 方法3:兼容.NET Framework老版本
DateTime localFromOldWay = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(timestamp).ToLocalTime();
Console.WriteLine("转换结果(兼容老版本):" + localFromOldWay.ToString("yyyy/MM/dd HH:mm:ss"));

这三种写法的核心都是:从UTC基准的起始时间开始计算,再转换到本地时区,这样就能得到正确的本地时间了。

总结一下

  • Unix时间戳没有“本地/UTC”之分,它就是UTC基准的绝对时间点,同一时刻的本地和UTC时间转出来的戳必然相同;
  • 转回时间时,一定要从UTC起始点出发,再转本地时区,别搞混起始时间的时区属性。

备注:内容来源于stack exchange,提问作者Hellagur

火山引擎 最新活动