🕐
← 返回教學列表

如何一次轉換多個 Unix 時間戳

· 標籤: batch-processing, log-analysis, automation, unix-timestamp, shell-scripting, data-processing

為什麼要批次轉換時間戳?

當您處理伺服器日誌、資料庫匯出、API 回應或分析資料集時,很少一次只遇到一個時間戳。現實世界的資料通常包含分佈在檔案、欄位或 JSON 酬載中的數千或數百萬個 Unix 時間戳。手動逐一轉換是不切實際的。批次處理可將堆積如山的原始數字變成可讀的時間線。

本指南涵蓋了使用命令列工具、腳本和我們的線上工具轉換多個時間戳的實用方法。

方法一:使用線上批次轉換器

我們的 Unix 時間戳轉換器 支援批次輸入。貼上多個時間戳(每行一個或以逗號分隔),工具會一次全部轉換,在按時區排序的表格中顯示結果。

這種方法適合中等規模的批次——數十到數百個時間戳——當您需要快速、可視化的結果而無需撰寫程式碼時。

方法二:命令列批次處理

使用 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

方法三:從日誌檔案中提取時間戳

日誌檔案常包含嵌入在結構化或半結構化文字中的時間戳。以下是常見日誌格式的實用技巧。

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

方法四:使用 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("轉換完成。輸出已寫入 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')}")

方法五:使用 awk 進行串流轉換

對於非常大的檔案(數百萬行),awk 以串流方式處理資料,無需將所有內容載入記憶體:

#!/usr/bin/awk -f
# batch-convert.awk
# 將第一個欄位作為 Unix 時間戳轉換,列印所有欄位及日期

{
    ts = $1
    # awk 的 mktime 需要 "YYYY MM DD HH MM SS" 格式
    # 我們透過 date 命令呼叫 shell 進行轉換
    cmd = "date -d @" ts " \"+%Y-%m-%d %H:%M:%S\""
    cmd | getline date
    close(cmd)
    print date, $0
}

用法:

./batch-convert.awk server.log

方法六:使用 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-1 萬) | ~30 秒 | 低 | | xargs 平行處理 | 中(1 萬-10 萬) | ~10 秒 | 低 | | Python | 任意大小 | ~2 秒 | 中 | | awk 串流 | 非常大(數百萬) | ~5 秒 | 中 | | SQL | 資料庫資料 | 即時 | 低 |

對於日常快速批次處理,使用我們的 Unix 時間戳轉換器。對於自動化和大型資料集,使用符合您工作流程的程式化方法進行腳本轉換。