不喜欢广告? 无广告 今天

Unix时间戳 如何转换以及为何无处不在

发布日期

一个关于处理Unix时间戳的实用参考:秒与毫秒的区别,JavaScript、Python、SQL和bash中的转换方法,应避免的时间区陷阱,以及在何时使用时间戳而非ISO 86及字符串。

Unix 时间戳:如何转换以及为何无处不在 1
广告 移除?
Unix时间戳:如何转换以及为何无处不在

Unix 时间戳是自 1970 年 1 月 1 日 00:00:00 UTC(也称为 Unix 时代)以来经过的秒数。这个日期并非出于技术原因被选择,而是当时设计 Unix 时的当前年份。该时间戳始终以 UTC 为准,这意味着像这样的时间戳 1712800000 在地球上每个地方都表示同一时刻,与时区无关。

Unix 时间戳被广泛使用:HTTP 头部、JWT 令牌、数据库记录、日志文件、消息队列和 API 响应。如果你正在构建或调试任何涉及时间的项目,你将频繁遇到它们。该 IO Tools Unix 时间戳转换器 对于快速查找非常有用,但你还需要知道如何在代码中处理它们。

秒与毫秒:导致所有人出错的 bug

生产环境中最常见的时间戳错误:混淆秒和毫秒。Unix 标准使用 。JavaScript 的 Date.now() 返回 毫秒。Java 的 System.currentTimeMillis().

也如此。时间戳 1712800000 对应的是 2024 年 4 月。时间戳 1712800000000 (毫秒) 对应的是 56000 年左右。如果你的日期计算结果是几十年后,或者显示 1970-01-01,这几乎总是原因所在。

经验之谈:如果时间戳有 13 位数字,那就是毫秒;10 位数字,那就是秒。不确定时,除以 1000,看看结果是否合理。

按语言转换 Unix 时间戳

以下是你会实际使用的模式:

JavaScript

// Get current timestamp (milliseconds — divide by 1000 for seconds)
const tsMs = Date.now();           // e.g. 1712800000000
const tsSec = Math.floor(Date.now() / 1000); // e.g. 1712800000

// Convert seconds timestamp to Date object
const ts = 1712800000;
const date = new Date(ts * 1000);  // must multiply by 1000
console.log(date.toISOString());   // "2024-04-11T02:13:20.000Z"

// Convert Date back to Unix timestamp (seconds)
const tsBack = Math.floor(date.getTime() / 1000);

Python

from datetime import datetime, timezone

# Get current timestamp (seconds)
import time
ts = int(time.time())  # e.g. 1712800000

# Convert timestamp to datetime (UTC-aware)
dt = datetime.fromtimestamp(ts, tz=timezone.utc)
print(dt.isoformat())  # 2024-04-11T02:13:20+00:00

# Convert local-naive datetime to timestamp (risky — see timezone section)
ts_back = int(dt.timestamp())

SQL(MySQL / MariaDB)

-- Convert timestamp to datetime
SELECT FROM_UNIXTIME(1712800000);
-- Result: 2024-04-11 02:13:20 (server timezone applies here)

-- Get current Unix timestamp
SELECT UNIX_TIMESTAMP();

-- Convert datetime string to timestamp
SELECT UNIX_TIMESTAMP('2024-04-11 02:13:20');

Bash

# Get current timestamp
date +%s

# Convert timestamp to human-readable (GNU date)
date -d @1712800000
# Output: Thu Apr 11 02:13:20 UTC 2024

# macOS (BSD date)
date -r 1712800000

快速参考表

语言获取当前时间(秒)时间戳 → 日期日期 → 时间戳
JavaScriptMath.floor(Date.now()/1000)new Date(ts * 1000)Math.floor(d.getTime()/1000)
Pythonint(time.time())datetime.fromtimestamp(ts, tz=timezone.utc)int(dt.timestamp())
MySQLUNIX_TIMESTAMP()FROM_UNIXTIME(ts)UNIX_TIMESTAMP(datetime_str)
Bashdate +%sdate -d @tsdate -d "2024-04-11" +%s

时区陷阱

Unix 时间戳始终是 UTC。始终如此。数字 1712800000 没有时区——它只是从时代开始计算秒数。时区是显示问题,而不是存储问题。

开发者容易遇到的问题:

  • Python 的 datetime.fromtimestamp(ts) 没有 tz=timezone.utc ——使用服务器本地时区,静默地进行。使用 fromtimestamp(ts, tz=timezone.utc) 反而。
  • MySQL 的 FROM_UNIXTIME() ——转换为 MySQL 服务器的时区设置(@@session.time_zone)。如果您的服务器位于 UTC+8,结果将提前 8 小时。
  • 在 MySQL 中存储 datetime 而不进行 UTC 标准化 ——如果您的应用程序服务器和数据库服务器处于不同时区,每次插入或读取都可能成为等待发生的错误。

避免所有这些问题的模式是:在数据库中存储 Unix 时间戳,在应用程序层在显示时将其转换为可读格式,并使用用户的首选时区。

时间戳与 ISO 8601 字符串:应该存储什么

两者都是有效的存储格式。权衡如下:

  • Unix 时间戳(整数):紧凑,适合比较和算术运算,没有时区歧义,适用于所有数据库引擎。缺点:没有工具就无法直接读取。
  • ISO 8601 字符串 (例如 2024-04-11T02:13:20Z):在数据库中可读,自我文档化。缺点:范围查询较慢,时区可能被意外省略或错误。

对于大多数应用程序:将时间戳存储为整数。在 API 和日志中使用 ISO 8601 以确保可读性。如果必须存储 ISO 8601,始终包含 Z 或明确的偏移——一个没有时区的 2024-04-11 02:13:20 在分布式系统中是灾难。

2038 问题

32 位有符号整数能存储的最大值为 2147483647,对应于 2038 年 1 月 19 日 03:14:07 UTC。使用 32 位 int 存储 Unix 时间戳的系统将在那一刻溢出——回滚到 1901 年或崩溃。

需要担心吗?如果你编写新代码,不需要——使用 64 位整数。如果你维护旧的 C 代码、嵌入式固件或使用 INT(11) 的旧 MySQL 模式存储时间戳,值得进行审计。MySQL 的 TIMESTAMP 类型也受影响; DATETIME 不受影响。使用 64 位时间戳的现代系统可以安全运行到 2920 亿年。

需要快速转换时间戳而无需编写代码?IO Tools 的 Unix 时间戳转换器 支持秒和毫秒,同时显示 UTC 和本地时间,并允许你粘贴一个日期以获取时间戳。

想要享受无广告的体验吗? 立即无广告

安装我们的扩展

将 IO 工具添加到您最喜欢的浏览器,以便即时访问和更快地搜索

添加 Chrome 扩展程序 添加 边缘延伸 添加 Firefox 扩展 添加 Opera 扩展

记分板已到达!

记分板 是一种有趣的跟踪您游戏的方式,所有数据都存储在您的浏览器中。更多功能即将推出!

广告 移除?
广告 移除?
广告 移除?

新闻角 包含技术亮点

参与其中

帮助我们继续提供有价值的免费工具

给我买杯咖啡
广告 移除?