在 C# 中解析 Unix 时间戳:从时间戳到 DateTime 及反向转换

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为什么 Unix 时间戳不仅仅是一个数字

\n

每个与 API、数据库或日志打交道的开发者,迟早都会遇到 Unix 时间戳。它是一个整数(或浮点数),表示自 1970 年 1 月 1 日 00:00:00 UTC 以来经过的秒数——即所谓的 Unix 纪元。

\n

但是,当你在服务器响应中看到数字 1719878400 时,你的大脑无法立刻说出:“啊,这是 2024 年 7 月 2 日”。我们需要将其转换为熟悉的 DateTime。反之亦然——将日期保存为时间戳以便传输。

\n

在 Stack Overflow 上,问题 “如何将 Unix 时间戳转换为 DateTime 以及反向转换?” 获得了数十万次浏览。这意味着即使是经验丰富的 C# 开发者有时也会在细节上感到困惑。在本文中,我们不仅会提供现成的解决方案,还会深入 底层:剖析 DateTime、DateTimeOffset、时钟周期和时区是如何工作的。

\n\n

Unix 时间戳到底是什么?

\n

在编写代码之前,让我们先统一术语。Unix 时间戳 是从 UTC 时间 1970 年 1 月 1 日午夜开始经过的秒数(有时是毫秒数)。重要的是:这是一个绝对的时间点,不依赖于时区。正因如此,它在分布式系统中非常方便使用。

\n

在 C# 中,我们使用两种主要类型:

\n
    \n
  • DateTime — 经典类型,可以是 UTC 时间,也可以是本地时间(通过 Kind 属性)。
  • \n
  • DateTimeOffset — 更现代的类型,显式存储与 UTC 的偏移量。推荐用于新项目。
  • \n
\n

在底层,DateTime 存储自公元 0001 年 1 月 1 日以来的 时钟周期 数(100 纳秒间隔)。而 Unix 时间戳只是自 1970 年以来的秒数。要在两者之间转换,需要计算这两个纪元之间的差值。

\n\n

Unix 时间戳与 DateTime 的相互转换——基本方法

\n

从 .NET Framework 4.6 和 .NET Core 开始,C# 中引入了内置方法,使生活更简单。让我们来看看它们。

\n\n

1. 从 Unix 时间戳(秒)到 DateTime

\n

最简单的方法是使用 DateTimeOffset.FromUnixTimeSeconds()。它返回一个 DateTimeOffset,然后可以将其转换为 DateTime。

\n
long unixTimestamp = 1719878400; // 2024 年 7 月 2 日, 00:00:00 UTC\n\n// 获取 DateTimeOffset\nDateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(unixTimestamp);\n\n// 转换为 DateTime (UTC)\nDateTime utcDateTime = dateTimeOffset.UtcDateTime;\n\nConsole.WriteLine(utcDateTime); // 02.07.2024 0:00:00
\n

如果你需要本地时间(例如,向用户显示),请使用 dateTimeOffset.LocalDateTime。但要小心:本地时间取决于服务器或计算机的设置。

\n\n

2. 从 DateTime 到 Unix 时间戳

\n

反向转换——通过 DateTimeOffset 的 ToUnixTimeSeconds() 方法。

\n
DateTime utcDateTime = new DateTime(2024, 7, 2, 0, 0, 0, DateTimeKind.Utc);\n\n// 创建显式指定 UTC 的 DateTimeOffset\nDateTimeOffset dateTimeOffset = new DateTimeOffset(utcDateTime);\n\nlong unixTimestamp = dateTimeOffset.ToUnixTimeSeconds();\n\nConsole.WriteLine(unixTimestamp); // 1719878400
\n

至关重要的是:在创建要转换的 DateTime 时,始终指定 DateTimeKind.Utc。如果不这样做,DateTimeOffset 会认为时间是本地时间,你将得到错误的时间戳——会偏移你的时区。

\n\n

3. 处理毫秒

\n

有时时间戳以毫秒为单位传递(例如,来自 JavaScript)。为此,请使用

博客

书籍推荐