datetimeoffset.fromunixtimeseconds 是 .net core 2.1+ 和 .net 5+ 中最安全、推荐的秒级 unix 时间戳转换方式,默认按 utc 解析,输入需为 long 类型,毫秒级需先除以 1000 取整;老版 framework 需手动用 timespan.fromseconds 加到 1970-01-01 utc 起始点;切勿用 datetime.parse 解析纯数字时间戳;注意保留 offset 信息,避免隐式转 datetime 导致时区丢失。

DateTimeOffset.FromUnixTimeSeconds 可直接转秒级时间戳
.NET Core 2.1+ 和 .NET 5+ 原生支持 UNIX 时间戳转换,DateTimeOffset.FromUnixTimeSeconds 是最安全、最推荐的方式。它默认按 UTC 解析,避免时区误判。
- 输入必须是
long类型(不能是int,否则超 2038 年会溢出) - 时间戳为 0 表示 1970-01-01T00:00:00Z,不是本地时间
- 如果你拿到的是毫秒级(比如 JavaScript 的
Date.now()),先除以 1000 再取整:timestampMs / 1000 - 转完后如需本地时间,用
.ToLocalTime(),但注意这会丢失原始时区信息
long unixSec = 1717027200; DateTimeOffset dt = DateTimeOffset.FromUnixTimeSeconds(unixSec); // 结果:2024-05-30T00:00:00+00:00
老版本 .NET Framework 用 TimeSpan 构造
.NET Framework 4.6 之前没有内置方法,得手动算。核心是把时间戳当秒数加到 UNIX 起始点上:
- 起始点是
new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc) - 必须指定
DateTimeKind.Utc,否则后续转本地时间会错乱 - 直接用
TimeSpan.FromSeconds(unixSec)加上去,别用AddSeconds(它对DateTime有隐式本地化风险)
long unixSec = 1717027200;
DateTime utc = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)
.AddSeconds(unixSec);
别用 DateTime.Parse 或 Convert.ToDateTime 解析时间戳
时间戳是纯数字,不是日期字符串。用 DateTime.Parse("1717027200") 会抛 FormatException,因为解析器不认识这种格式。
-
Convert.ToDateTime同样失败,且在某些文化环境下可能静默转成奇怪日期 - 即使加了
TryParse,也只会返回false,不报错反而更难排查 - 真遇到字符串形式的时间戳(比如 JSON 里传的
"1717027200"),先long.TryParse,再走上面任一构造方式
时区处理最容易漏掉的一环
DateTimeOffset.FromUnixTimeSeconds 返回的是带偏移的 DateTimeOffset,但很多人直接调 .DateTime 取 DateTime,结果丢掉了 Offset 信息,后续跨系统传输或存数据库就出问题。
- 如果要存进 SQL Server 的
datetimeoffset字段,直接用dt(不用 .DateTime) - 如果必须用
DateTime,明确选.UtcDateTime或.LocalDateTime,别依赖隐式转换 - 日志里打印时,用
ToString("o")而不是ToString(),确保时区信息可见
事情说清了就结束。UNIX 时间戳本身没时区,但 C# 里每一步构造和转换都暗含时区假设,盯住 DateTimeKind 和 Offset 就不会翻车。











