🕐
← Quay lại hướng dẫn

Cách chuyển đổi nhiều dấu thời gian Unix cùng lúc

· Thẻ: batch-processing, log-analysis, automation, unix-timestamp, shell-scripting, data-processing

Tại sao cần chuyển đổi hàng loạt dấu thời gian?

Khi bạn làm việc với nhật ký máy chủ, xuất cơ sở dữ liệu, phản hồi API hoặc tập dữ liệu phân tích, bạn hiếm khi gặp một dấu thời gian đơn lẻ tại một thời điểm. Dữ liệu thực tế thường chứa hàng nghìn hoặc hàng triệu dấu thời gian Unix trải rộng trên các tệp, cột hoặc tải trọng JSON. Chuyển đổi thủ công từng cái một là không thực tế. Xử lý hàng loạt biến hàng núi số thô thành các dòng thời gian có thể đọc được.

Hướng dẫn này bao gồm các cách tiếp cận thực tế để chuyển đổi nhiều dấu thời gian bằng công cụ dòng lệnh, script và công cụ trực tuyến của chúng tôi.

Phương pháp 1: Sử dụng trình chuyển đổi hàng loạt trực tuyến

Trình chuyển đổi dấu thời gian Unix của chúng tôi hỗ trợ nhập hàng loạt. Dán nhiều dấu thời gian (mỗi dòng một cái hoặc phân tách bằng dấu phẩy) và công cụ sẽ chuyển đổi tất cả cùng một lúc, hiển thị kết quả trong một bảng được sắp xếp theo múi giờ.

Điều này lý tưởng cho các lô có kích thước vừa phải — hàng chục đến hàng trăm dấu thời gian — khi bạn cần kết quả trực quan nhanh chóng mà không cần viết mã.

Phương pháp 2: Xử lý hàng loạt bằng dòng lệnh

Vòng lặp cơ bản với lệnh date

# Chuyển đổi danh sách dấu thời gian bằng vòng lặp bash
for ts in 1785292800 1785379200 1785465600 1785552000; do
    date -d @"$ts" "+%Y-%m-%d %H:%M:%S"
done

Đọc từ một tệp

# timestamps.txt chứa một dấu thời gian trên mỗi dòng
while read -r ts; do
    date -d @"$ts" "+%Y-%m-%d %H:%M:%S"
done < timestamps.txt

Sử dụng xargs để xử lý song song

# Đối với tệp lớn, sử dụng xargs với nhiều tiến trình
cat timestamps.txt | xargs -P 4 -I {} date -d "@{}" "+%Y-%m-%d %H:%M:%S"

Xuất ra tệp CSV

# Tạo CSV với dấu thời gian gốc và ngày đã chuyển đổi
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

Phương pháp 3: Trích xuất dấu thời gian từ tệp nhật ký

Tệp nhật ký thường chứa dấu thời gian được nhúng trong văn bản có cấu trúc hoặc bán cấu trúc. Dưới đây là các kỹ thuật thực tế cho các định dạng nhật ký phổ biến.

Nhật ký truy cập Apache / Nginx

Nhật ký Apache và Nginx thường sử dụng định dạng %{%Y-%m-%d}T hoặc, nếu được cấu hình, dấu thời gian Unix:

# Trích xuất và chuyển đổi dấu thời gian từ nhật ký Nginx
# Các dòng nhật ký có thể chứa: [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

Nhật ký JSON

Các ứng dụng hiện đại thường ghi nhật ký ở định dạng JSON:

# Sử dụng jq để trích xuất dấu thời gian từ tệp nhật ký JSON
cat app.log | jq -r '.timestamp' | while read -r ts; do
    date -d @"$ts" "+%Y-%m-%d %H:%M:%S"
done

Nhật ký phân cách tùy chỉnh

# Nếu dấu thời gian là trường đầu tiên trong nhật ký (phân cách bằng dấu gạch đứng)
awk -F'|' '{ts=$1; cmd="date -d @" ts " \"+%Y-%m-%d %H:%M:%S\""; cmd | getline date; close(cmd); print date, $0}' server.log

Phương pháp 4: Sử dụng Python để xử lý hàng loạt nâng cao

Python là công cụ linh hoạt nhất cho chuyển đổi hàng loạt, đặc biệt khi dấu thời gian cần lọc, biến đổi hoặc xuất.

Chuyển đổi danh sách dấu thời gian

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))

Xử lý tệp 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")
        
        # Bạn có thể thay thế bằng múi giờ địa phương của mình
        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("Chuyển đổi hoàn tất. Đầu ra được ghi vào converted.csv")

Lọc theo phạm vi ngày

from datetime import datetime

# Xác định phạm vi: đầu và cuối tháng 7 năm 2026
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]

# Chỉ lọc tháng 7 năm 2026
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')}")

Phương pháp 5: Sử dụng awk để chuyển đổi luồng

Đối với các tệp rất lớn (hàng triệu dòng), awk xử lý dữ liệu dưới dạng luồng mà không tải mọi thứ vào bộ nhớ:

#!/usr/bin/awk -f
# batch-convert.awk
# Chuyển đổi trường đầu tiên thành dấu thời gian Unix, in tất cả các trường với ngày

{
    ts = $1
    # mktime của awk mong đợi "YYYY MM DD HH MM SS"
    # Chúng ta gọi shell để chuyển đổi qua lệnh date
    cmd = "date -d @" ts " \"+%Y-%m-%d %H:%M:%S\""
    cmd | getline date
    close(cmd)
    print date, $0
}

Cách sử dụng:

./batch-convert.awk server.log

Phương pháp 6: Sử dụng SQL cho dấu thời gian trong cơ sở dữ liệu

Nếu dấu thời gian của bạn nằm trong cơ sở dữ liệu, hãy để SQL thực hiện công việc:

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;

Định dạng bảng đầu ra

# Tạo bảng được định dạng đẹp với tiêu đề cột
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")"
}

So sánh hiệu suất

| Phương pháp | Phù hợp nhất | Tốc độ (10K dấu thời gian) | Độ phức tạp | |--------|----------|----------------------|--------------| | Trình chuyển đổi trực tuyến | Lô nhỏ (< 50) | Ngay lập tức | Không | | Vòng lặp Bash | Nhỏ-vừa (50-10K) | ~30s | Thấp | | xargs song song | Vừa (10K-100K) | ~10s | Thấp | | Python | Mọi kích thước | ~2s | Trung bình | | Luồng awk | Rất lớn (hàng triệu) | ~5s | Trung bình | | SQL | Dữ liệu cơ sở dữ liệu | Ngay lập tức | Thấp |

Đối với các lô nhanh hàng ngày, hãy sử dụng Trình chuyển đổi dấu thời gian Unix của chúng tôi. Đối với tự động hóa và tập dữ liệu lớn, hãy viết script chuyển đổi bằng cách tiếp cận lập trình phù hợp với quy trình làm việc của bạn.