DevToolBox免费
博客

Unix 时间戳转日期:JavaScript、Python、Bash、SQL 等语言转换方法

7 分钟阅读作者 DevToolBox

Unix 时间戳(也称 Epoch 时间或 POSIX 时间)是计算机中最通用的时间表示方式之一。本指南将展示如何在 JavaScript、Python、Bash、SQL、PHP 和 Go 中将 Unix 时间戳转换为可读日期,附带可直接复制的代码示例。

试试我们的 Unix 时间戳转换工具

1. 什么是 Unix 时间戳?

Unix 时间戳是从 1970 年 1 月 1 日 00:00:00 UTC(即 Unix 纪元)起经过的秒数。它是一个整数,可以无歧义地表示一个时间点,不受时区影响。

某些系统(特别是 JavaScript 和 Java)使用毫秒而非秒。毫秒时间戳是秒的 1000 倍,例如:1700000000(秒)vs 1700000000000(毫秒)。

关键特性:Unix 时间戳始终是 UTC 时间,始终是整数(或浮点数用于亚秒精度),始终从同一纪元开始计数。负值表示 1970 年之前的日期。

Unix Epoch:  January 1, 1970 00:00:00 UTC
Timestamp:   0

Current:     ~1700000000  (November 2023)
             = 1,700,000,000 seconds since epoch

In milliseconds: 1700000000000  (13 digits)
In seconds:      1700000000     (10 digits)

2. JavaScript:new Date()、toISOString()、Intl.DateTimeFormat

JavaScript 的 Date 构造函数接受毫秒时间戳。如果你有秒级 Unix 时间戳,需要先乘以 1000。

基本转换(秒转日期)

const timestamp = 1700000000; // seconds

// Convert to Date object (multiply by 1000 for milliseconds)
const date = new Date(timestamp * 1000);

console.log(date);
// Tue Nov 14 2023 22:13:20 GMT+0000 (UTC)

console.log(date.toUTCString());
// "Tue, 14 Nov 2023 22:13:20 GMT"

console.log(date.toLocaleDateString());
// "11/14/2023" (varies by locale)

ISO 8601 字符串

const timestamp = 1700000000;
const date = new Date(timestamp * 1000);

console.log(date.toISOString());
// "2023-11-14T22:13:20.000Z"

// Parse back to timestamp
const parsed = Date.parse("2023-11-14T22:13:20.000Z");
console.log(parsed / 1000);
// 1700000000

使用 Intl.DateTimeFormat 进行本地化格式化

const timestamp = 1700000000;
const date = new Date(timestamp * 1000);

// US English
const usFormat = new Intl.DateTimeFormat('en-US', {
  dateStyle: 'full',
  timeStyle: 'long',
  timeZone: 'America/New_York'
}).format(date);
// "Tuesday, November 14, 2023 at 5:13:20 PM EST"

// Japanese
const jpFormat = new Intl.DateTimeFormat('ja-JP', {
  dateStyle: 'full',
  timeStyle: 'long',
  timeZone: 'Asia/Tokyo'
}).format(date);
// "2023年11月15日水曜日 7:13:20 JST"

// Chinese
const cnFormat = new Intl.DateTimeFormat('zh-CN', {
  year: 'numeric', month: '2-digit', day: '2-digit',
  hour: '2-digit', minute: '2-digit', second: '2-digit',
  timeZone: 'Asia/Shanghai'
}).format(date);
// "2023/11/15 06:13:20"

提取日期各部分

const timestamp = 1700000000;
const date = new Date(timestamp * 1000);

const year   = date.getUTCFullYear();  // 2023
const month  = date.getUTCMonth() + 1; // 11 (0-indexed, so +1)
const day    = date.getUTCDate();       // 14
const hours  = date.getUTCHours();      // 22
const mins   = date.getUTCMinutes();    // 13
const secs   = date.getUTCSeconds();    // 20

// Get current timestamp
const now = Math.floor(Date.now() / 1000);

3. Python:datetime.fromtimestamp(),时区感知

Python 的 datetime 模块提供了简洁的时间戳转换。始终使用时区感知方法以避免歧义。

基本转换

from datetime import datetime

timestamp = 1700000000

# Basic conversion (returns local time!)
dt = datetime.fromtimestamp(timestamp)
print(dt)
# 2023-11-14 22:13:20 (in your local timezone)

# Format as string
print(dt.strftime("%Y-%m-%d %H:%M:%S"))
# "2023-11-14 22:13:20"

时区感知(推荐)

from datetime import datetime, timezone

timestamp = 1700000000

# UTC (recommended approach)
dt_utc = datetime.fromtimestamp(timestamp, tz=timezone.utc)
print(dt_utc)
# 2023-11-14 22:13:20+00:00

print(dt_utc.isoformat())
# "2023-11-14T22:13:20+00:00"

# Get current UTC timestamp
import time
current_ts = int(time.time())
print(current_ts)

转换到其他时区

from datetime import datetime, timezone
from zoneinfo import ZoneInfo  # Python 3.9+

timestamp = 1700000000

# Convert to Tokyo time
tokyo = datetime.fromtimestamp(timestamp, tz=ZoneInfo("Asia/Tokyo"))
print(tokyo)
# 2023-11-15 07:13:20+09:00

# Convert to New York time
ny = datetime.fromtimestamp(timestamp, tz=ZoneInfo("America/New_York"))
print(ny)
# 2023-11-14 17:13:20-05:00

# Convert to Shanghai time
shanghai = datetime.fromtimestamp(timestamp, tz=ZoneInfo("Asia/Shanghai"))
print(shanghai)
# 2023-11-15 06:13:20+08:00

毫秒时间戳

from datetime import datetime, timezone

ms_timestamp = 1700000000000  # 13 digits = milliseconds

# Divide by 1000 to get seconds
dt = datetime.fromtimestamp(ms_timestamp / 1000, tz=timezone.utc)
print(dt)
# 2023-11-14 22:13:20+00:00

4. Bash/Shell:date -d @timestamp、macOS date -r

Linux 和 macOS 的 date 命令语法不同。以下是两种方式。

Linux(GNU date)

# Linux (GNU coreutils date)
date -d @1700000000
# Tue Nov 14 22:13:20 UTC 2023

# With UTC explicitly
date -u -d @1700000000
# Tue Nov 14 22:13:20 UTC 2023

# ISO 8601 format
date -d @1700000000 --iso-8601=seconds
# 2023-11-14T22:13:20+00:00

macOS(BSD date)

# macOS (BSD date) - uses -r instead of -d @
date -r 1700000000
# Tue Nov 14 22:13:20 UTC 2023

# With UTC
date -u -r 1700000000
# Tue Nov 14 22:13:20 UTC 2023

获取当前 Unix 时间戳

# Works on both Linux and macOS
date +%s
# 1700000000 (current timestamp in seconds)

# Milliseconds (Linux)
date +%s%N | cut -b1-13

# Milliseconds (macOS with Python)
python3 -c "import time; print(int(time.time() * 1000))"

自定义格式

# Linux
date -d @1700000000 "+%Y-%m-%d %H:%M:%S"
# 2023-11-14 22:13:20

# macOS
date -r 1700000000 "+%Y-%m-%d %H:%M:%S"
# 2023-11-14 22:13:20

# Common format specifiers:
# %Y = 4-digit year    %m = month (01-12)
# %d = day (01-31)     %H = hour (00-23)
# %M = minute (00-59)  %S = second (00-59)
# %Z = timezone name   %z = timezone offset

5. SQL:MySQL、PostgreSQL、SQLite

每个主流 SQL 数据库都有内置函数在 Unix 时间戳和日期之间转换。

MySQL:FROM_UNIXTIME()

-- MySQL: Convert timestamp to datetime
SELECT FROM_UNIXTIME(1700000000);
-- '2023-11-14 22:13:20'

-- With custom format
SELECT FROM_UNIXTIME(1700000000, '%Y-%m-%d %H:%i:%s');
-- '2023-11-14 22:13:20'

-- In a query
SELECT id, name, FROM_UNIXTIME(created_at) AS created_date
FROM users
WHERE created_at > UNIX_TIMESTAMP('2023-01-01');

PostgreSQL:to_timestamp()

-- PostgreSQL: Convert timestamp to date
SELECT to_timestamp(1700000000);
-- '2023-11-14 22:13:20+00'

-- With timezone
SELECT to_timestamp(1700000000) AT TIME ZONE 'America/New_York';
-- '2023-11-14 17:13:20'

-- Format output
SELECT to_char(to_timestamp(1700000000), 'YYYY-MM-DD HH24:MI:SS');
-- '2023-11-14 22:13:20'

SQLite:datetime()

-- SQLite: Convert timestamp to datetime string
SELECT datetime(1700000000, 'unixepoch');
-- '2023-11-14 22:13:20'

-- In local time
SELECT datetime(1700000000, 'unixepoch', 'localtime');
-- '2023-11-14 17:13:20' (depends on server timezone)

-- With strftime
SELECT strftime('%Y-%m-%d %H:%M:%S', 1700000000, 'unixepoch');
-- '2023-11-14 22:13:20'

反向:日期转 Unix 时间戳

-- MySQL: Date to Unix timestamp
SELECT UNIX_TIMESTAMP('2023-11-14 22:13:20');
-- 1700000000

-- PostgreSQL: Date to Unix timestamp
SELECT EXTRACT(EPOCH FROM TIMESTAMP '2023-11-14 22:13:20');
-- 1700000000

-- SQLite: Date to Unix timestamp
SELECT strftime('%s', '2023-11-14 22:13:20');
-- '1700000000'

6. PHP:date()、Carbon

PHP 有出色的内置日期/时间函数,以及流行的 Carbon 库提供更具表达力的代码。

内置 date()

<?php
$timestamp = 1700000000;

// Basic date() function
echo date('Y-m-d H:i:s', $timestamp);
// "2023-11-14 22:13:20"

// ISO 8601
echo date('c', $timestamp);
// "2023-11-14T22:13:20+00:00"

// RFC 2822 (email headers)
echo date('r', $timestamp);
// "Tue, 14 Nov 2023 22:13:20 +0000"

// Current timestamp
echo time();
// current Unix timestamp in seconds

DateTime 类

<?php
$timestamp = 1700000000;

// DateTime class (more flexible)
$dt = new DateTime("@$timestamp");
$dt->setTimezone(new DateTimeZone('UTC'));
echo $dt->format('Y-m-d H:i:s T');
// "2023-11-14 22:13:20 UTC"

// Convert to other timezone
$dt->setTimezone(new DateTimeZone('Asia/Shanghai'));
echo $dt->format('Y-m-d H:i:s T');
// "2023-11-15 06:13:20 CST"

// DateTimeImmutable (thread-safe)
$dti = (new DateTimeImmutable("@$timestamp"))
    ->setTimezone(new DateTimeZone('America/New_York'));
echo $dti->format('Y-m-d H:i:s T');
// "2023-11-14 17:13:20 EST"

Carbon 库(Laravel)

<?php
use Carbon\Carbon;

$timestamp = 1700000000;

// Carbon (popular in Laravel)
$date = Carbon::createFromTimestamp($timestamp);
echo $date->toDateTimeString();
// "2023-11-14 22:13:20"

echo $date->diffForHumans();
// "X months ago"

echo $date->timezone('Asia/Tokyo')->format('Y-m-d H:i:s');
// "2023-11-15 07:13:20"

// From milliseconds
$ms = Carbon::createFromTimestampMs(1700000000000);

7. Go:time.Unix()

Go 的 time 包提供了 Unix() 函数进行简洁的时间戳转换。

基本转换

package main

import (
    "fmt"
    "time"
)

func main() {
    timestamp := int64(1700000000)

    // Convert seconds to time.Time
    t := time.Unix(timestamp, 0)
    fmt.Println(t.UTC())
    // 2023-11-14 22:13:20 +0000 UTC

    fmt.Println(t.UTC().String())
    // "2023-11-14 22:13:20 +0000 UTC"
}

自定义格式化

package main

import (
    "fmt"
    "time"
)

func main() {
    t := time.Unix(1700000000, 0).UTC()

    // Go uses a reference time: Mon Jan 2 15:04:05 MST 2006
    fmt.Println(t.Format("2006-01-02 15:04:05"))
    // "2023-11-14 22:13:20"

    fmt.Println(t.Format(time.RFC3339))
    // "2023-11-14T22:13:20Z"

    fmt.Println(t.Format(time.RFC1123))
    // "Tue, 14 Nov 2023 22:13:20 UTC"

    // With timezone
    loc, _ := time.LoadLocation("Asia/Tokyo")
    fmt.Println(t.In(loc).Format("2006-01-02 15:04:05 MST"))
    // "2023-11-15 07:13:20 JST"

    // Get current timestamp
    now := time.Now().Unix()
    fmt.Println(now)
}

毫秒时间戳

package main

import (
    "fmt"
    "time"
)

func main() {
    msTimestamp := int64(1700000000000) // milliseconds

    // Unix() takes (seconds, nanoseconds)
    t := time.Unix(0, msTimestamp*int64(time.Millisecond))
    fmt.Println(t.UTC())
    // 2023-11-14 22:13:20 +0000 UTC

    // Or divide by 1000
    t2 := time.Unix(msTimestamp/1000, 0)
    fmt.Println(t2.UTC())
    // 2023-11-14 22:13:20 +0000 UTC
}

8. 毫秒 vs 秒:如何识别和转换

处理时间戳时最常见的 Bug 之一就是混淆秒和毫秒。以下是区分和转换方法。

  • 秒级时间戳通常是 10 位数字(如 1700000000),表示 2020 年代的日期。
  • 毫秒时间戳通常是 13 位数字(如 1700000000000)。
  • 如果时间戳产生了公元 50000 年以后的日期,你可能把毫秒传给了期望秒的函数。
  • 如果时间戳产生了 1970 年 1 月的日期,你可能把秒传给了期望毫秒的函数。

快速转换公式

// Detect: count digits
function isMilliseconds(ts) {
  return ts.toString().length >= 13;
}

// Seconds to milliseconds
const ms = seconds * 1000;

// Milliseconds to seconds
const sec = Math.floor(milliseconds / 1000);

// Auto-detect and normalize to seconds
function toSeconds(ts) {
  return ts > 9999999999 ? Math.floor(ts / 1000) : ts;
}

// Python equivalent
def to_seconds(ts):
    return ts // 1000 if ts > 9999999999 else ts

9. 值得关注的 Unix 时间戳

一些 Unix 时间戳在计算机历史和未来中具有特殊意义。

时间戳日期(UTC)意义
01970-01-01 00:00:00Unix 纪元(起点)
-141829401969-07-20 20:17:40人类登月(负时间戳)
9466848002000-01-01 00:00:00千年虫(Y2K,2000年)
10000000002001-09-09 01:46:40第 10 亿秒
20000000002033-05-18 03:33:20第 20 亿秒
21474836472038-01-19 03:14:0732 位溢出(2038 年问题) (有符号 32 位整数最大值)
# Verify notable timestamps yourself:

# Bash (Linux)
date -u -d @0                # Thu Jan  1 00:00:00 UTC 1970
date -u -d @946684800        # Sat Jan  1 00:00:00 UTC 2000
date -u -d @2147483647       # Tue Jan 19 03:14:07 UTC 2038

# Python
from datetime import datetime, timezone
datetime.fromtimestamp(2147483647, tz=timezone.utc)
# datetime(2038, 1, 19, 3, 14, 7, tzinfo=timezone.utc)

# JavaScript
new Date(2147483647 * 1000).toISOString()
// "2038-01-19T03:14:07.000Z"

10. 时区陷阱:UTC vs 本地时间

时区处理是时间戳相关 Bug 的头号来源。以下是需要记住的关键规则。

  • Unix 时间戳始终是 UTC。不存在"本地" Unix 时间戳。
  • 在 JavaScript 中调用 new Date(ts * 1000) 时,Date 对象内部存储 UTC,但 .toString() 会以用户的本地时区显示。
  • Python 的 datetime.fromtimestamp() 默认返回本地时间。使用 datetime.fromtimestamp(ts, tz=timezone.utc) 获取 UTC。
  • 始终以 UTC 存储时间戳,仅在显示时转换为本地时间。
  • 注意夏令时(DST)转换。同一本地时间可能出现两次(秋季回拨)或完全不存在(春季前拨)。

JavaScript:UTC vs 本地输出对比

const timestamp = 1700000000;
const date = new Date(timestamp * 1000);

// These are DIFFERENT if you're not in UTC:
console.log(date.toString());
// "Tue Nov 14 2023 17:13:20 GMT-0500 (Eastern Standard Time)"
//  ^ Local time

console.log(date.toUTCString());
// "Tue, 14 Nov 2023 22:13:20 GMT"
//  ^ UTC time

console.log(date.toISOString());
// "2023-11-14T22:13:20.000Z"
//  ^ Always UTC (the Z means Zulu/UTC)

// Safe: always use UTC methods
console.log(date.getUTCHours());   // 22 (UTC)
console.log(date.getHours());       // 17 (local, if EST)
# Python timezone comparison
from datetime import datetime, timezone
from zoneinfo import ZoneInfo

ts = 1700000000

# WRONG: naive datetime (no timezone info)
naive = datetime.fromtimestamp(ts)
print(naive)  # ambiguous - depends on server timezone

# RIGHT: timezone-aware
utc = datetime.fromtimestamp(ts, tz=timezone.utc)
print(utc)    # 2023-11-14 22:13:20+00:00

# Convert between zones safely
eastern = utc.astimezone(ZoneInfo("America/New_York"))
print(eastern)  # 2023-11-14 17:13:20-05:00

# The underlying timestamp is always the same
print(utc.timestamp() == eastern.timestamp())  # True

常见问题

什么是 Unix 时间戳?

Unix 时间戳(也称 Epoch 时间或 POSIX 时间)是从 1970 年 1 月 1 日 00:00:00 UTC 起经过的秒数。它是一种不依赖时区的方式,用一个整数表示特定的时间点。

为什么 JavaScript 使用毫秒而不是秒?

JavaScript 的 Date 对象设计上与 Java 的 java.util.Date 一致,使用毫秒以获得更高精度。在 JavaScript 中处理 Unix 时间戳时,始终将秒乘以 1000:new Date(timestamp * 1000)。

什么是 2038 年问题?

将 Unix 时间戳存储为有符号 32 位整数的系统将在 2038 年 1 月 19 日 03:14:07 UTC 发生溢出,届时值超过 2,147,483,647。时间戳将变为负数,导致日期跳回 1901 年。大多数现代系统已使用 64 位整数,不会在 2920 亿年内溢出。

如何获取当前 Unix 时间戳?

JavaScript:Math.floor(Date.now() / 1000)。Python:import time; int(time.time())。Bash:date +%s。PHP:time()。Go:time.Now().Unix()。都返回 UTC 自纪元以来的秒数。

Unix 时间戳可以是负数吗?

可以。负 Unix 时间戳表示 1970 年 1 月 1 日之前的日期。例如,-1 表示 1969 年 12 月 31 日 23:59:59 UTC。1969 年 7 月 20 日的人类登月时间戳为 -14182940。大多数现代语言和数据库都能正确处理负时间戳。

试试我们的 Unix 时间戳转换工具
𝕏 Twitterin LinkedIn
这篇文章有帮助吗?

保持更新

获取每周开发技巧和新工具通知。

无垃圾邮件,随时退订。

试试这些相关工具

🕐Unix Timestamp Converter⏱️Unix Timestamp ConverterCron Expression Parser

相关文章

Cron 表达式实例:每 5 分钟、每天、每周、每月

通过实用示例掌握 cron 表达式。学习如何设置每 5 分钟、每小时、每天、每周和每月的定时任务。

JavaScript 日期格式化完全指南

学习 JavaScript 中所有日期格式化方法:toLocaleDateString、Intl.DateTimeFormat、ISO 字符串,以及 date-fns 和 dayjs 等库。