🕐
← 返回教程列表

如何一次转换多个 Unix 时间戳

· 标签: batch-processing, log-analysis, automation, unix-timestamp, shell-scripting, data-processing

为什么要批量转换时间戳?

当你处理服务器日志、数据库导出、API 响应或分析数据集时,很少会一次只遇到一个时间戳。真实世界的数据通常包含分散在文件、列或 JSON 负载中的成千上万甚至数以百万计的 Unix 时间戳。手动转换每一个是不现实的。批处理能将海量的原始数字转化为可读的时间线。

本指南介绍了使用命令行工具、脚本和我们的在线工具转换多个时间戳的实用方法。

方法 1:使用在线批量转换器

我们的 Unix 时间戳转换器 支持批量输入。粘贴多个时间戳(每行一个或用逗号分隔),工具会一次性转换所有时间戳,并以按时区排序的表格显示结果。

这非常适合中等规模的批次——几十到几百个时间戳——此时你需要快速、直观的结果,而无需编写代码。

方法 2:命令行批处理

使用 date 命令的基本循环

# 使用 bash 循环转换一组时间戳
for ts in 1785292800 1785379200 1785465600 1785552000; do
    date -d @"$ts" "+%Y-%m-%d %H:%M:%S"
done

从文件读取

# timestamps.txt 每行包含一个时间戳
while read -r ts; do
    date -d @"$ts" "+%Y-%m-%d %H:%M:%S"
done < timestamps.txt

使用 xargs 进行并行处理

# 对于大文件,使用带多进程的 xargs
cat timestamps.txt | xargs -P 4 -I {} date -d "@{}" "+%Y-%m-%d %H:%M:%S"

输出到 CSV 文件

# 生成包含原始时间戳和转换后日期的 CSV
echo "timestamp,date_utc,date_local" > output.csv
while read -r ts; do
    utc_date=$(TZ=UTC date -d @"$ts" "+%Y-%m-%d %H:%M:%S")
    local_date=$(date -d @"$ts" "+%Y-%m-%d %H:%M:%S")
    echo "$ts,$utc_date,$local_date" >> output.csv
done < timestamps.txt

方法 3:从日志文件中提取时间戳

日志文件通常包含嵌入在结构化或半结构化文本中的时间戳。以下是一些常见日志格式的实用技巧。

Apache / Nginx 访问日志

Apache 和 Nginx 日志通常使用 %{%Y-%m-%d}T 格式,或者如果配置了的话,使用 Unix 时间戳:

# 从 Nginx 日志中提取并转换时间戳
# 日志行可能包含: [1785292800] GET /index.html 200
grep -oP '\[\K[0-9]{10}(?=\])' access.log | while read -r ts; do
    date -d @"$ts" "+%Y-%m-%d %H:%M:%S"
done

JSON 日志

现代应用通常以 JSON 格式记录日志:

# 使用 jq 从 JSON 日志文件中提取时间戳
cat app.log | jq -r '.timestamp' | while read -r ts; do
    date -d @"$ts" "+%Y-%m-%d %H:%M:%S"
done

自定义分隔符日志

# 如果时间戳是日志中的第一个字段(管道符分隔)
awk -F'|' '{ts=$1; cmd="date -d @" ts " \"+%Y-%m-%d %H:%M:%S\""; cmd | getline date; close(cmd); print date, $0}' server.log

方法 4:使用 Python 进行高级批处理

Python 是批量转换最灵活的工具,尤其是当时间戳需要过滤、转换或导出时。

转换一组时间戳

from datetime import datetime
import json

timestamps = [1785292800, 1785379200, 1785465600, 1785552000]

results = []
for ts in timestamps:
    dt = datetime.utcfromtimestamp(ts)
    results.append({
        "timestamp": ts,
        "datetime_utc": dt.strftime("%Y-%m-%d %H:%M:%S"),
        "date": dt.strftime("%Y-%m-%d"),
        "time": dt.strftime("%H:%M:%S"),
        "day_of_week": dt.strftime("%A"),
    })

print(json.dumps(results, indent=2))

处理 CSV 文件

import csv
from datetime import datetime

with open("data.csv", "r") as infile, open("converted.csv", "w", newline="") as outfile:
    reader = csv.DictReader(infile)
    writer = csv.DictWriter(outfile, fieldnames=reader.fieldnames + ["date_utc", "date_local"])
    writer.writeheader()
    
    for row in reader:
        ts = int(row["timestamp"])
        dt_utc = datetime.utcfromtimestamp(ts)
        row["date_utc"] = dt_utc.strftime("%Y-%m-%d %H:%M:%S")
        
        # 你可以将此替换为你的本地时区
        from datetime import timezone
        dt_local = datetime.fromtimestamp(ts, tz=timezone.utc).astimezone()
        row["date_local"] = dt_local.strftime("%Y-%m-%d %H:%M:%S %Z")
        
        writer.writerow(row)

print("Conversion complete. Output written to converted.csv")

按日期范围过滤

from datetime import datetime

# 定义范围:2026 年 7 月的开始和结束
start_ts = int(datetime(2026, 7, 1).timestamp())
end_ts   = int(datetime(2026, 7, 31, 23, 59, 59).timestamp())

timestamps = [1785292800, 1785379200, 1785465600, 1785552000,
              1234567890, 1000000000]

# 只过滤出 2026 年 7 月的数据
july_only = [ts for ts in timestamps if start_ts <= ts <= end_ts]

for ts in july_only:
    dt = datetime.utcfromtimestamp(ts)
    print(f"{ts} -> {dt.strftime('%Y-%m-%d %H:%M:%S')}")

方法 5:使用 awk 进行流式转换

对于非常大的文件(数百万行),awk 以流的方式处理数据,无需将全部数据加载到内存中:

#!/usr/bin/awk -f
# batch-convert.awk
# 将第一个字段作为 Unix 时间戳转换,输出所有字段并附带日期

{
    ts = $1
    # awk 的 mktime 期望 "YYYY MM DD HH MM SS" 格式
    # 我们调用 shell 的 date 命令进行转换
    cmd = "date -d @" ts " \"+%Y-%m-%d %H:%M:%S\""
    cmd | getline date
    close(cmd)
    print date, $0
}

用法:

./batch-convert.awk server.log

方法 6:使用 SQL 处理数据库时间戳

如果你的时间戳在数据库中,让 SQL 来完成这项工作:

PostgreSQL

SELECT 
    id,
    event_time,
    to_timestamp(event_time) AS readable_time,
    to_char(to_timestamp(event_time), 'YYYY-MM-DD HH24:MI:SS') AS formatted_time
FROM events
WHERE to_timestamp(event_time) >= '2026-07-01';

MySQL

SELECT 
    id,
    event_time,
    FROM_UNIXTIME(event_time) AS readable_time,
    FROM_UNIXTIME(event_time, '%Y-%m-%d %H:%i:%s') AS formatted_time
FROM events
WHERE FROM_UNIXTIME(event_time) >= '2026-07-01';

SQLite

SELECT 
    id,
    event_time,
    datetime(event_time, 'unixepoch') AS readable_time,
    strftime('%Y-%m-%d %H:%M:%S', event_time, 'unixepoch') AS formatted_time
FROM events;

格式化输出表格

# 创建带列标题的精美格式化表格
convert() {
    printf "%-15s %-25s %-25s\n" "TIMESTAMP" "UTC" "LOCAL"
    printf "%-15s %-25s %-25s\n" "---------------" "-------------------------" "-------------------------"
    while read -r ts; do
        utc=$(TZ=UTC date -d @"$ts" "+%Y-%m-%d %H:%M:%S")
        local=$(date -d @"$ts" "+%Y-%m-%d %H:%M:%S")
        printf "%-15s %-25s %-25s\n" "$ts" "$utc" "$local"
    done <<< "$(cat "$1")"
}

性能对比

| 方法 | 最适合 | 速度(1 万个时间戳) | 复杂度 | |--------|----------|----------------------|------------| | 在线转换器 | 小批次(< 50) | 即时 | 无 | | Bash 循环 | 中小规模(50-10K) | 约 30 秒 | 低 | | xargs 并行 | 中等规模(10K-100K) | 约 10 秒 | 低 | | Python | 任意规模 | 约 2 秒 | 中等 | | awk 流式 | 超大规模(数百万) | 约 5 秒 | 中等 | | SQL | 数据库数据 | 即时 | 低 |

对于快速、日常的批次,使用我们的 Unix 时间戳转换器。对于自动化和大型数据集,使用与你工作流匹配的编程方法编写脚本进行转换。