首页 > 工具箱 > Unix 时间戳转换

Unix 时间戳转换

时间戳与日期时间双向互转,秒 / 毫秒 / 微秒 / 纳秒自动识别,可切换任意时区,另附 20 种编程语言与数据库的写法。

时区只影响「普通时间」的显示与解析,时间戳本身与时区无关。

当前 Unix 时间戳

--

取的是本机时间,本机时钟不准这里也会不准。

时间戳 → 普通时间

按位数自动判断单位:10 位为秒、13 位为毫秒、16 位为微秒、19 位为纳秒。

普通时间 → 时间戳

支持 2026-09-21 12:00:00、2026/9/21、2026年9月21日、2026-09-21T12:00:00Z、2026-09-21T12:00:00+08:00 等写法;只写日期按当天零点算。带 Z 或 ±时区后缀时,以写法里的时区为准。

什么是 Unix 时间戳

Unix 时间戳(Unix timestamp),也叫 Unix 时间(Unix time)、POSIX 时间(POSIX time)、纪元时间(Epoch time),是从协调世界时(UTC)1970 年 1 月 1 日 00:00:00 起到当前时刻所经过的总秒数,不计闰秒。它起源于 Unix 系统,如今在类 Unix 系统、Windows、各类数据库和几乎所有编程语言里都被广泛采用。
时间戳是一个纯数字,本身不带时区。同一个时间戳在北京是 12:00,在伦敦就是 04:00 —— 变的只是显示方式,数值完全一样。所以在接口传参、日志记录、数据库存储里用时间戳,可以彻底绕开时区和夏令时的坑,只在展示给人看的那一步再按时区格式化。
常见的精度有四种:秒(10 位,如 1774000000)、毫秒(13 位,Java 的 System.currentTimeMillis、JavaScript 的 Date.now 都是它)、微秒(16 位)、纳秒(19 位,Go 的 UnixNano)。拿到一串数字先数位数,基本就能判断单位;两个系统对接时单位不一致,是时间对不上最常见的原因。
用 32 位有符号整数存秒级时间戳时,最大值是 2147483647,对应 UTC 的 2038-01-19 03:14:07,再往后就会溢出成负数,这就是所谓的「2038 年问题」(Y2K38)。现在新写的代码应该用 64 位整型存时间戳。
另外注意 Unix 时间戳不包含闰秒:闰秒发生时,同一个时间戳会被复用一秒,所以它严格来说不是「自 1970 年以来真实流逝的秒数」,而是一种按每天固定 86400 秒计算的约定。

各编程语言的时间戳写法

点代码即可复制。示例中的 ts 代表秒级时间戳,s 代表时间字符串。

获取当前 Unix 时间戳

语言代码备注
JavaScript Math.floor(Date.now() / 1000) Date.now() 本身是毫秒
Java Instant.now().getEpochSecond() 旧写法 System.currentTimeMillis() / 1000L
PHP time() 毫秒用 (int)(microtime(true) * 1000)
Python import time
int(time.time())
time.time() 返回带小数的秒
Go time.Now().Unix() 毫秒 time.Now().UnixMilli()
C# / .NET DateTimeOffset.UtcNow.ToUnixTimeSeconds() .NET Framework 4.6+
Ruby Time.now.to_i
Rust SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() 需 use std::time::{SystemTime, UNIX_EPOCH}
C / C++ time(NULL) 头文件 time.h
Swift Int(Date().timeIntervalSince1970)
Kotlin System.currentTimeMillis() / 1000
Perl time
Lua os.time()
Shell date +%s Linux / macOS 通用
MySQL SELECT UNIX_TIMESTAMP() 等价 UNIX_TIMESTAMP(NOW())
PostgreSQL SELECT EXTRACT(EPOCH FROM NOW())
SQL Server SELECT DATEDIFF(s, '1970-01-01', GETUTCDATE()) 2038 年后请用 DATEDIFF_BIG
SQLite SELECT strftime('%s', 'now')
Oracle SELECT (SYSDATE - TO_DATE('1970-01-01', 'YYYY-MM-DD')) * 86400 FROM dual SYSDATE 为数据库服务器本地时间
Excel =(NOW() - DATE(1970,1,1)) * 86400 - 8 * 3600 单元格是北京时间,所以减 8 小时

Unix 时间戳 → 普通时间

语言代码备注
JavaScript new Date(ts * 1000).toLocaleString() 按浏览器所在时区显示
Java LocalDateTime.ofInstant(Instant.ofEpochSecond(ts), ZoneId.of("Asia/Shanghai"))
PHP date('Y-m-d H:i:s', $ts) 受 date_default_timezone_set 影响
Python import time
time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(ts))
UTC 用 time.gmtime(ts)
Go time.Unix(ts, 0).Format("2006-01-02 15:04:05") Go 的格式串是固定的参考时间
C# / .NET DateTimeOffset.FromUnixTimeSeconds(ts).LocalDateTime
Ruby Time.at(ts).strftime('%Y-%m-%d %H:%M:%S')
Rust chrono::DateTime::from_timestamp(ts, 0).unwrap() 需 chrono crate
C / C++ time_t t = ts;
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", localtime(&t));
Swift Date(timeIntervalSince1970: TimeInterval(ts))
Kotlin Instant.ofEpochSecond(ts).atZone(ZoneId.systemDefault())
Perl scalar localtime($ts)
Lua os.date('%Y-%m-%d %H:%M:%S', ts)
Shell date -d @ts '+%F %T' # GNU / Linux
date -r ts '+%F %T' # macOS / BSD
两个系统参数不一样
MySQL SELECT FROM_UNIXTIME(ts) 可带格式 FROM_UNIXTIME(ts, '%Y-%m-%d')
PostgreSQL SELECT TO_TIMESTAMP(ts)
SQL Server SELECT DATEADD(s, ts, '1970-01-01 00:00:00') 结果是 UTC 时间
SQLite SELECT datetime(ts, 'unixepoch', 'localtime')
Oracle SELECT TO_DATE('1970-01-01', 'YYYY-MM-DD') + ts / 86400 FROM dual
Excel =(ts + 8 * 3600) / 86400 + DATE(1970,1,1) 再把单元格设成日期格式

普通时间 → Unix 时间戳

语言代码备注
JavaScript Math.floor(new Date('2026-09-21T12:00:00+08:00').getTime() / 1000) 写全时区才不会因浏览器时区而变
Java LocalDateTime.parse("2026-09-21T12:00:00").toEpochSecond(ZoneOffset.ofHours(8))
PHP strtotime('2026-09-21 12:00:00') 也可 mktime(12, 0, 0, 9, 21, 2026)
Python from datetime import datetime
int(datetime.strptime('2026-09-21 12:00:00', '%Y-%m-%d %H:%M:%S').timestamp())
Go t, _ := time.ParseInLocation("2006-01-02 15:04:05", s, time.Local)
t.Unix()
time.Parse 按 UTC 解析
C# / .NET new DateTimeOffset(dt, TimeSpan.FromHours(8)).ToUnixTimeSeconds()
Ruby require 'time'
Time.parse('2026-09-21 12:00:00').to_i
Rust NaiveDateTime::parse_from_str(s, "%Y-%m-%d %H:%M:%S")?.and_utc().timestamp() 需 chrono crate
C / C++ struct tm tm = {0};
strptime("2026-09-21 12:00:00", "%Y-%m-%d %H:%M:%S", &tm);
mktime(&tm);
mktime 按本地时区
Swift formatter.date(from: s)!.timeIntervalSince1970 formatter 为 DateFormatter
Kotlin LocalDateTime.parse(s).atZone(ZoneId.systemDefault()).toEpochSecond()
Perl use Time::Local;
timelocal($sec, $min, $hour, $day, $mon - 1, $year)
月份从 0 开始
Lua os.time({year = 2026, month = 9, day = 21, hour = 12, min = 0, sec = 0})
Shell date -d '2026-09-21 12:00:00' +%s # GNU
date -j -f '%Y-%m-%d %H:%M:%S' '2026-09-21 12:00:00' +%s # macOS
MySQL SELECT UNIX_TIMESTAMP('2026-09-21 12:00:00') 按会话 time_zone 解释
PostgreSQL SELECT EXTRACT(EPOCH FROM TIMESTAMP '2026-09-21 12:00:00')
SQL Server SELECT DATEDIFF(s, '1970-01-01 00:00:00', '2026-09-21 12:00:00')
SQLite SELECT strftime('%s', '2026-09-21 12:00:00') 字符串按 UTC 解释
Oracle SELECT (TO_DATE('2026-09-21 12:00:00', 'YYYY-MM-DD HH24:MI:SS')
- TO_DATE('1970-01-01', 'YYYY-MM-DD')) * 86400 FROM dual
Excel =(A1 - DATE(1970,1,1)) * 86400 - 8 * 3600 A1 为北京时间的日期单元格

几个常被用到的时间戳

时间戳北京时间(UTC+8)说明
0 1970-01-01 08:00:00 Unix 纪元起点,UTC 的 1970-01-01 00:00:00
1000000000 2001-09-09 09:46:40 十亿秒,时间戳首次进到 10 位
1234567890 2009-02-14 07:31:30 被程序员当节日过的顺序数
1500000000 2017-07-14 10:40:00
2000000000 2033-05-18 11:33:20
2147483647 2038-01-19 11:14:07 32 位有符号整数上限,即「2038 年问题」
4102444800 2100-01-01 08:00:00 UTC 的 2100-01-01 00:00:00