Epoch 时间到底是什么?
如果你在编程中处理过日期和时间,一定遇到过 Unix 时间戳。但它们到底是什么,我们为什么要使用它们呢?
Unix epoch 时间(也叫 Unix 时间、POSIX 时间,或简称"epoch")用一个数字来表示某个时刻,这个数字是自 1970 年 1 月 1 日午夜 UTC(协调世界时)以来经过的秒数。这个特定的时刻被称为"Unix 纪元"或"纪元零点"。
为什么是 1970 年 1 月 1 日?
这个日期看起来有点随意,但它是在 20 世纪 70 年代初贝尔实验室开发 Unix 时选定的。开发人员需要为他们的时间跟踪系统设定一个一致的起点,而 1970 年 1 月 1 日正好接近他们开发项目的时间。从那以后,它就成为了通用标准。
理解格式
Unix 时间戳根据所需精度有不同的格式:
- 秒(10 位数字): 标准格式,如
1728773400 - 毫秒(13 位数字): 更高精度,如
1728773400000 - 微秒(16 位数字): 超高精度计时,如
1728773400000000
常见时间间隔的秒数
了解这些常见间隔可以帮助你更直观地使用时间戳:
| 时间周期 | 秒数 | 快速计算 |
|---|---|---|
| 1 小时 | 3,600 | 60 × 60 |
| 1 天 | 86,400 | 24 × 3,600 |
| 1 周 | 604,800 | 7 × 86,400 |
| 1 个月(平均) | 2,629,743 | 30.44 × 86,400 |
| 1 年(平均) | 31,556,926 | 365.24 × 86,400 |
2038 年问题(Y2038)
这里有个重要的事:许多系统将 Unix 时间戳存储为 32 位有符号整数。这会产生一个类似于千年虫的问题。
32 位有符号整数最多只能计数到 2,147,483,647 秒。一旦到达 2038 年 1 月 19 日 03:14:07 UTC,这个计数器就会溢出并回绕成负数,可能导致系统故障和 bug。
获取当前 Epoch 时间
每种编程语言都有自己获取当前 Unix 时间戳的方法。以下是最常见的方法:
Web 开发
JavaScript
// 获取毫秒时间戳,除以 1000 得到秒
const timestamp = Math.floor(Date.now() / 1000);
// 另一种方法
const timestamp = Math.floor(new Date().getTime() / 1000);
PHP
// 简单直接
$timestamp = time();
// 使用 DateTime(更灵活)
$timestamp = (new DateTime())->getTimestamp();
后端语言
Python
import time
# 获取当前时间戳
timestamp = int(time.time())
# 使用 datetime 模块
from datetime import datetime
timestamp = int(datetime.now().timestamp())
Java
// 返回毫秒,除以 1000 得到秒
long timestamp = System.currentTimeMillis() / 1000;
// 使用 Instant (Java 8+)
long timestamp = Instant.now().getEpochSecond();
C#
// .NET Framework 4.6+ / .NET Core
long timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
// 旧版本
var epoch = (DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds;
Ruby
# 获取当前时间戳
timestamp = Time.now.to_i
# 另一种方法
timestamp = Time.new.to_i
Go
import "time"
// 获取当前 Unix 时间戳
timestamp := time.Now().Unix()
// 获取毫秒
milliseconds := time.Now().UnixMilli()
数据库查询
MySQL
-- 获取当前时间戳
SELECT UNIX_TIMESTAMP();
-- 从特定日期获取时间戳
SELECT UNIX_TIMESTAMP('2025-10-12 14:30:00');
PostgreSQL
-- 获取当前时间戳
SELECT EXTRACT(EPOCH FROM NOW());
-- 从特定日期
SELECT EXTRACT(EPOCH FROM TIMESTAMP '2025-10-12 14:30:00');
SQLite
-- 获取当前时间戳
SELECT STRFTIME('%s', 'now');
-- 从特定日期
SELECT STRFTIME('%s', '2025-10-12 14:30:00');
命令行
Unix/Linux Shell
# 获取当前时间戳
date +%s
# 将特定日期转换为时间戳
date +%s -d "2025-10-12 14:30:00"
# 对于 UTC/GMT 时间,使用 -ud 而不是 -d
date +%s -ud "2025-10-12 14:30:00"
PowerShell
# 获取当前时间戳
[int][double]::Parse((Get-Date (Get-Date).ToUniversalTime() -UFormat %s))
从 Epoch 转换为可读日期
当你有了 Unix 时间戳后,通常需要将它转换回可读的日期格式:
JavaScript
// 将时间戳转换为 Date 对象
const date = new Date(timestamp * 1000); // 乘以 1000 转换为毫秒
// 格式化
console.log(date.toLocaleString()); // 本地格式
console.log(date.toISOString()); // ISO 8601 格式
PHP
// 格式化时间戳
$date = date('Y-m-d H:i:s', $timestamp);
// RFC 2822 格式
$date = date('r', $timestamp);
// 使用 DateTime
$date = (new DateTime())->setTimestamp($timestamp)->format('Y-m-d H:i:s');
Python
from datetime import datetime
# 转换为 datetime 对象
dt = datetime.fromtimestamp(timestamp)
# 格式化
formatted = dt.strftime('%Y-%m-%d %H:%M:%S')
# 对于 UTC
dt_utc = datetime.utcfromtimestamp(timestamp)
MySQL
-- 将时间戳转换为 datetime
SELECT FROM_UNIXTIME(1728773400);
-- 使用自定义格式
SELECT FROM_UNIXTIME(1728773400, '%Y-%m-%d %H:%i:%s');
从可读日期转换为 Epoch
相反的操作同样重要:
JavaScript
// 将日期字符串解析为时间戳
const timestamp = Math.floor(new Date('2025-10-12 14:30:00').getTime() / 1000);
// 使用 Date.parse()
const timestamp = Math.floor(Date.parse('October 12, 2025') / 1000);
PHP
// 解析大多数英文日期文本
$timestamp = strtotime('15 November 2025');
$timestamp = strtotime('next Monday');
$timestamp = strtotime('+1 week');
// 使用 DateTime
$timestamp = (new DateTime('2025-10-12 14:30:00'))->getTimestamp();
Python
from datetime import datetime
import time
# 解析日期字符串
dt = datetime.strptime('2025-10-12 14:30:00', '%Y-%m-%d %H:%M:%S')
timestamp = int(dt.timestamp())
# 对于 UTC
import calendar
timestamp = calendar.timegm(time.strptime('2025-10-12 14:30:00', '%Y-%m-%d %H:%M:%S'))
最佳实践
在应用程序中使用 Unix 时间戳时:
- 始终使用 64 位整数以避免 Y2038 问题
- 在数据库中存储 UTC 时间戳,仅在显示时转换为本地时间
- 保持一致的精度(秒 vs 毫秒)贯穿整个应用程序
- 记录你的格式 —— 明确说明你使用的是秒还是毫秒
- 考虑使用时区感知库来处理复杂的日期/时间操作
- 永远不要在没有时区信息的情况下存储本地时间作为时间戳
总结
Unix 时间戳是编程中的基本概念,每个开发者都应该理解。它们提供了一种简单、通用的时间表示方式,适用于所有系统和编程语言。
无论你是在构建 Web 应用、处理数据库,还是只是需要调度任务,理解 epoch 时间都会让你的工作轻松很多。使用我们的 Unix 时间戳转换器工具可以快速在时间戳和可读日期之间进行转换!