正在加载,请稍候…

JavaScript 和 Python 中的 Unix 时间戳:转换、比较、格式化

在 JavaScript 和 Python 中处理 Unix 时间戳的完整代码参考——获取当前时间、转换为日期、处理时区,并避免毫秒与秒的陷阱。

Unix Timestamp in JavaScript and Python: Convert, Compare, Format

大多数开发者容易搞错的一件事

最常见的 Unix 时间戳错误是静默发生的:JavaScript 的 Date.now() 返回毫秒,而 Python 的 time.time() 返回。将 JavaScript 时间戳传递给期望秒数的 Python 函数,你会得到一个公元 33658 年的日期。这种不匹配永远不会抛出错误——它只会静默地破坏你的数据。

本指南涵盖了每种常见的时间戳操作,并提供了两种语言的可复制粘贴代码。

Unix Timestamp in JavaScript and Python: Convert, Compare, Format illustration

什么是 Unix 时间戳?

Unix 时间戳是从 1970 年 1 月 1 日 00:00:00 UTC(Unix 纪元)开始经过的秒数(或毫秒数)。它没有时区。它不代表本地时间。它是一个单一的整数,在世界上的每台计算机上都表示相同的含义。

当前时间戳:你可以通过 Unix 时间戳转换器 实时查看。

JavaScript:毫秒级时间戳

// 获取当前时间戳(毫秒)
const nowMs = Date.now();              // 例如 1717200000000
const nowMs2 = new Date().getTime();   // 相同

// 获取当前时间戳(秒——用于期望 Unix 时间的 API)
const nowSec = Math.floor(Date.now() / 1000);  // 例如 1717200000

// 将时间戳转换为 Date 对象
const date = new Date(1717200000000);  // 传入毫秒
console.log(date.toISOString());       // "2024-06-01T00:00:00.000Z"

// 将秒级时间戳转换为 Date(先乘以 1000!)
const fromSeconds = new Date(1717200000 * 1000);

// Date 转换为时间戳(毫秒)
const ts = new Date('2024-06-01').getTime();  // 1717200000000

// Date 转换为时间戳(秒)
const tsSec = Math.floor(new Date('2024-06-01').getTime() / 1000);

Unix Timestamp in JavaScript and Python: Convert, Compare, Format illustration

Python:秒级时间戳(浮点数)

import time
import datetime

# 获取当前时间戳(秒,浮点数)
now_sec = time.time()           # 例如 1717200000.123
now_int = int(time.time())      # 整数秒

# 将时间戳转换为 datetime(UTC)
dt_utc = datetime.datetime.fromtimestamp(1717200000, tz=datetime.timezone.utc)
print(dt_utc.isoformat())       # "2024-06-01T00:00:00+00:00"

# 将时间戳转换为本地 datetime(注意夏令时)
dt_local = datetime.datetime.fromtimestamp(1717200000)
# 使用系统时区——在不同机器上行为可能不同

# datetime 转换为时间戳
dt = datetime.datetime(2024, 6, 1, tzinfo=datetime.timezone.utc)
ts = dt.timestamp()             # 1717200000.0

# 当前 UTC datetime 转换为时间戳
ts_now = datetime.datetime.now(datetime.timezone.utc).timestamp()

毫秒与秒的问题

语言/平台 单位 示例值
JavaScript Date.now() 毫秒 1717200000000
JavaScript Date.getTime() 毫秒 1717200000000
Python time.time() 秒(浮点数) 1717200000.0
Python datetime.timestamp() 秒(浮点数) 1717200000.0
Unix shell date +%s 1717200000
MySQL UNIX_TIMESTAMP() 1717200000
Java System.currentTimeMillis() 毫秒 1717200000000
Go time.Now().Unix() 1717200000
Go time.Now().UnixMilli() 毫秒 1717200000000

经验法则: 如果你的时间戳是 13 位数字,则是毫秒;如果是 10 位数字,则是秒。

// 在 JavaScript 中检测并归一化
function toMilliseconds(ts) {
  // 如果时间戳看起来像秒(10 位),则转换为毫秒
  if (ts < 1e12) return ts * 1000;
  return ts;
}

Unix Timestamp in JavaScript and Python: Convert, Compare, Format illustration

处理时区

Unix 时间戳与时区无关。复杂性在于将它们转换为人类可读的日期。

// JavaScript — 在特定时区显示
const ts = 1717200000000;
const date = new Date(ts);

// UTC
date.toISOString();  // "2024-06-01T00:00:00.000Z"

// 用户的本地时区
date.toLocaleString();  // 因系统而异

// 特定时区(Intl API)
date.toLocaleString('en-US', { timeZone: 'America/New_York' });
// "5/31/2024, 8:00:00 PM"

date.toLocaleString('en-US', { timeZone: 'Asia/Shanghai' });
// "6/1/2024, 8:00:00 AM"
# Python — 时区感知转换
import datetime

ts = 1717200000

# 始终显式使用 UTC——在服务器代码中永远不要依赖系统时区
utc = datetime.timezone.utc
dt_utc = datetime.datetime.fromtimestamp(ts, tz=utc)

# 转换为特定时区(需要 zoneinfo,Python 3.9+)
from zoneinfo import ZoneInfo
dt_ny = dt_utc.astimezone(ZoneInfo('America/New_York'))
print(dt_ny.isoformat())  # "2024-05-31T20:00:00-04:00"

计算时间差

// JavaScript — 自事件以来的时间
const eventTs = 1717200000000;  // 毫秒
const now = Date.now();
const diffSeconds = Math.floor((now - eventTs) / 1000);
const diffMinutes = Math.floor(diffSeconds / 60);
const diffHours = Math.floor(diffMinutes / 60);
const diffDays = Math.floor(diffHours / 24);

// 令牌是否过期?
function isExpired(expiryTimestampSeconds) {
  return Math.floor(Date.now() / 1000) > expiryTimestampSeconds;
}
# Python — 时间差
import time
import datetime

ts1 = 1717200000
ts2 = time.time()

diff_seconds = ts2 - ts1
diff_days = diff_seconds / 86400

# 使用 timedelta 获得可读的差值
dt1 = datetime.datetime.fromtimestamp(ts1, tz=datetime.timezone.utc)
dt2 = datetime.datetime.now(datetime.timezone.utc)
delta = dt2 - dt1
print(delta.days, "天,", delta.seconds // 3600, "小时")

常见陷阱

将时间戳存储为整数还是字符串: 在数据库中存储为整数,而不是字符串。将 1717200000 作为字符串比较会得到字典序,而不是时间顺序。

夏令时(DST): 当跨越本地时间的 DST 边界时,一天并不总是 86400 秒。始终在 UTC 时间戳中进行时间运算,然后格式化显示。

2038 年问题: 32 位有符号整数在 Unix 时间戳 2147483647(2038 年 1 月 19 日)处溢出。如果你在旧数据库中将时间戳存储在 32 位 INT 列中,请立即迁移到 64 位 BIGINT

Python 中的微秒: time.time() 返回一个具有亚秒精度的浮点数。如果你需要干净的整数秒值,请使用 int(time.time())

→ 使用 Unix 时间戳转换器 立即将任何 Unix 时间戳转换为人类可读的日期。