Time Zone ที่ตั้งค่าไม่ถูกต้องบน Server ทำให้ Log มี Timestamp ผิด, Cron Job รันผิดเวลา, Certificate Validation ล้มเหลว และการ Debug ทำได้ยากเพราะเวลาใน Log ไม่ตรงกับเวลาจริง การตั้งค่า Time Zone บน Linux ด้วย timedatectl และการ Sync เวลาด้วย NTP/chrony เป็นสิ่งที่ควรทำทันทีหลัง Provision Server ใหม่
บทความนี้ครอบคลุมการตั้งค่า Time Zone ด้วย timedatectl, การ Sync เวลาด้วย systemd-timesyncd และ chrony, การตรวจสอบ NTP Status, การตั้งค่า Hardware Clock, การจัดการ Time Zone ใน Application Layer (PHP, Python, MySQL) และการแก้ปัญหา Time Drift บน Cloud VPS
ตรวจสอบ Time Zone ปัจจุบัน
# ดู Time Zone และ NTP Status ทั้งหมด
timedatectl
# ตัวอย่าง Output:
# Local time: Thu 2026-04-16 09:00:00 +07
# Universal time: Thu 2026-04-16 02:00:00 UTC
# RTC time: Thu 2026-04-16 02:00:00
# Time zone: Asia/Bangkok (+07, +0700)
# System clock synchronized: yes
# NTP service: active
# RTC in local TZ: no
# ดู Time Zone ปัจจุบันแบบสั้น
date
date +%Z # ชื่อ Time Zone (เช่น +07)
date +%z # Offset (เช่น +0700)
timedatectl show --property=Timezone --value
# ดูไฟล์ localtime
ls -la /etc/localtime
cat /etc/timezone # บน Debian/Ubuntu
ตั้งค่า Time Zone ด้วย timedatectl
# ค้นหา Time Zone ที่ต้องการ
timedatectl list-timezones | grep -i asia
timedatectl list-timezones | grep -i bangkok
timedatectl list-timezones | grep -i singapore
# ตั้งค่า Time Zone เป็น Asia/Bangkok (ประเทศไทย UTC+7)
sudo timedatectl set-timezone Asia/Bangkok
# ตัวอย่าง Time Zone อื่น ๆ
sudo timedatectl set-timezone UTC # UTC (แนะนำสำหรับ Server)
sudo timedatectl set-timezone Asia/Singapore # สิงคโปร์ UTC+8
sudo timedatectl set-timezone Asia/Tokyo # ญี่ปุ่น UTC+9
sudo timedatectl set-timezone Europe/London # ลอนดอน
# ตรวจสอบผลลัพธ์
timedatectl
date
# วิธีที่ 2: ตั้งค่าโดยตรงผ่าน symlink (ถ้า timedatectl ไม่ available)
sudo ln -sf /usr/share/zoneinfo/Asia/Bangkok /etc/localtime
# บน Debian/Ubuntu เพิ่มเติม
echo "Asia/Bangkok" | sudo tee /etc/timezone
sudo dpkg-reconfigure -f noninteractive tzdata
# ตรวจสอบ zoneinfo files ที่มี
ls /usr/share/zoneinfo/Asia/
ls /usr/share/zoneinfo/
NTP Sync ด้วย systemd-timesyncd
systemd-timesyncd เป็น NTP Client แบบเบาที่มากับ systemd ใช้สำหรับ Sync เวลาจาก NTP Server เหมาะสำหรับ Client ทั่วไปที่ไม่ต้องการ NTP Server เต็มรูปแบบ
# ตรวจสอบสถานะ timesyncd
systemctl status systemd-timesyncd
# เปิดใช้งาน NTP Sync
sudo timedatectl set-ntp true
# ดู NTP Status
timedatectl show-timesync --all
# ดูข้อมูล NTP Server ที่เชื่อมต่อ
timedatectl timesync-status
# ตัวอย่าง Output:
# Server: 162.159.200.1 (time.cloudflare.com)
# Poll interval: 34min 8s (min: 32s; max 34min 8s)
# Leap: normal
# Version: 4
# Stratum: 3
# Reference: 8B7A2BDE
# Precision: 1us (-20)
# Root distance: 11.944ms (max: 5s)
# Offset: +1.273ms
# Delay: 4.990ms
# ตั้งค่า NTP Server สำหรับ timesyncd
sudo nano /etc/systemd/timesyncd.conf
# เพิ่มหรือแก้ไข:
[Time]
NTP=time.cloudflare.com ntp.ubuntu.com
FallbackNTP=0.th.pool.ntp.org 1.th.pool.ntp.org
RootDistanceMaxSec=5
PollIntervalMinSec=32
PollIntervalMaxSec=2048
# Restart service
sudo systemctl restart systemd-timesyncd
timedatectl timesync-status
NTP Sync ด้วย chrony (แนะนำสำหรับ Server)
chrony เป็น NTP Implementation ที่แม่นยำกว่า timesyncd เหมาะสำหรับ Server ที่ต้องการเวลาแม่นยำสูง หรือ Environment ที่ต้องเป็น NTP Server สำหรับ Client อื่น
# ติดตั้ง chrony
# Ubuntu/Debian
sudo apt install chrony -y
# RHEL/Rocky/AlmaLinux
sudo dnf install chrony -y
# เปิดใช้งาน
sudo systemctl enable --now chronyd
# ตรวจสอบสถานะ
chronyc tracking
# ตัวอย่าง Output:
# Reference ID : A29FC7EA (time.cloudflare.com)
# Stratum : 4
# Ref time (UTC) : Thu Apr 16 02:00:00 2026
# System time : 0.000001234 seconds fast of NTP time
# Last offset : +0.000001234 seconds
# RMS offset : 0.000001234 seconds
# Frequency : -1.234 ppm slow
# Residual freq : +0.001 ppm
# Skew : 0.123 ppm
# Root delay : 0.004990000 seconds
# Root dispersion : 0.000123456 seconds
# Update interval : 64.0 seconds
# Leap status : Normal
# ตั้งค่า chrony
sudo nano /etc/chrony.conf # RHEL/Rocky
sudo nano /etc/chrony/chrony.conf # Ubuntu/Debian
# ตัวอย่าง Configuration:
# ใช้ NTP Pool ของไทย
pool th.pool.ntp.org iburst maxsources 4
# หรือใช้ Cloudflare NTP (แนะนำ)
server time.cloudflare.com iburst
# NTP Server อื่น ๆ
server 0.th.pool.ntp.org iburst
server 1.th.pool.ntp.org iburst
server 2.th.pool.ntp.org iburst
server 3.th.pool.ntp.org iburst
# การตั้งค่าอื่น ๆ
makestep 1.0 3
rtcsync
driftfile /var/lib/chrony/drift
logdir /var/log/chrony
# Restart หลังแก้ไข Config
sudo systemctl restart chronyd
# คำสั่ง chronyc ที่ใช้บ่อย
chronyc sources -v # ดู NTP Sources ทั้งหมด
chronyc sourcestats # Statistics ของแต่ละ Source
chronyc tracking # Current Tracking Status
chronyc ntpdata # รายละเอียด NTP Data
chronyc makestep # Force Sync ทันที (หน้าที่เดียวกับ ntpdate -b)
# ดู Log
journalctl -u chronyd --since today
tail -f /var/log/chrony/tracking.log
Hardware Clock (RTC)
# ดู Hardware Clock (RTC)
sudo hwclock --show
# Sync Hardware Clock จาก System Clock
sudo hwclock --systohc
# Sync System Clock จาก Hardware Clock
sudo hwclock --hctosys
# ตั้งค่า Hardware Clock เป็น UTC (แนะนำเสมอ)
sudo timedatectl set-local-rtc 0
# ตรวจสอบว่า RTC ใช้ UTC หรือ Local Time
timedatectl | grep "RTC in local TZ"
# RTC in local TZ: no → RTC เก็บเป็น UTC (ถูกต้อง)
# RTC in local TZ: yes → RTC เก็บเป็น Local Time (ไม่แนะนำ)
Time Zone ใน Application Layer
แม้ว่า System Time Zone จะถูกต้อง Application แต่ละตัวอาจใช้ Time Zone Setting ของตัวเอง ต้องตั้งค่าแยกสำหรับแต่ละ Stack
# PHP — ตั้งค่า date.timezone ใน php.ini
sudo nano /etc/php/8.2/fpm/php.ini
# หรือ
sudo nano /etc/php/8.2/cli/php.ini
# แก้ไข:
date.timezone = Asia/Bangkok
# ตรวจสอบ
php -r "echo date_default_timezone_get();"
php -r "echo date('Y-m-d H:i:s T');"
# หรือตั้งค่าใน Code (ไม่แนะนำ — ควรตั้งใน php.ini)
# date_default_timezone_set('Asia/Bangkok');
# Python — ตั้งค่า Environment Variable
export TZ="Asia/Bangkok"
# หรือใน Python Code
import os
os.environ['TZ'] = 'Asia/Bangkok'
import time
time.tzset()
# ใช้ pytz หรือ zoneinfo (Python 3.9+)
from zoneinfo import ZoneInfo
from datetime import datetime
now_bkk = datetime.now(ZoneInfo("Asia/Bangkok"))
print(now_bkk)
# ตั้งค่าใน systemd service
# /etc/systemd/system/myapp.service
# [Service]
# Environment=TZ=Asia/Bangkok
# MySQL/MariaDB — ตั้งค่า Time Zone
# ดู Time Zone ปัจจุบัน
mysql -u root -p -e "SELECT @@global.time_zone, @@session.time_zone, NOW();"
# ตั้งค่าใน my.cnf
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
# เพิ่ม:
[mysqld]
default-time-zone = '+07:00'
# หรือ
default-time-zone = 'Asia/Bangkok'
# ถ้าใช้ชื่อ Time Zone ต้อง Load Timezone Tables ก่อน
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql
sudo systemctl restart mysql
# ตั้งค่า Session Time Zone ใน Query
SET time_zone = '+07:00';
SET GLOBAL time_zone = '+07:00';
# PostgreSQL — ตั้งค่า Time Zone
# ดู Time Zone ปัจจุบัน
psql -c "SHOW timezone;"
psql -c "SELECT NOW(), current_setting('timezone');"
# ตั้งค่าใน postgresql.conf
sudo nano /etc/postgresql/16/main/postgresql.conf
# แก้ไข:
timezone = 'Asia/Bangkok'
# ตั้งค่า per Session
SET timezone TO 'Asia/Bangkok';
# ตั้งค่า per User
ALTER USER myuser SET timezone TO 'Asia/Bangkok';
ตรวจสอบและแก้ปัญหา Time Drift
#!/bin/bash
# /usr/local/bin/check-time.sh
# ตรวจสอบ Time Sync Status
echo "=== Time Status Check ==="
echo "Current Time: $(date)"
echo "Time Zone: $(timedatectl show --property=Timezone --value)"
echo ""
# ตรวจสอบ NTP Sync
NTP_STATUS=$(timedatectl show --property=NTPSynchronized --value)
echo "NTP Synchronized: ${NTP_STATUS}"
if [ "$NTP_STATUS" != "yes" ]; then
echo "⚠️ WARNING: NTP is NOT synchronized!"
fi
# ตรวจสอบ chrony (ถ้าติดตั้ง)
if command -v chronyc >/dev/null 2>&1; then
echo ""
echo "=== chrony Status ==="
chronyc tracking | grep -E "System time|Last offset|Stratum"
fi
# ตรวจสอบ Time Offset กับ NTP Server
if command -v ntpdate >/dev/null 2>&1; then
echo ""
echo "=== NTP Offset (ntpdate dry-run) ==="
ntpdate -q pool.ntp.org 2>&1 | tail -1
fi
echo ""
echo "=== Log Timestamp Test ==="
echo "If log timestamps match expected time, timezone is correct."
journalctl --since "1 minute ago" --until "now" -n 3 --no-pager 2>/dev/null | head -5
# แก้ปัญหา Time Drift บน Cloud VPS
# Cloud VPS บางครั้งมี Time Drift เพราะ Virtual Clock ไม่แม่นยำ
# ตรวจสอบ Drift
chronyc tracking | grep "System time"
# System time : 0.500000000 seconds slow of NTP time
# ถ้าเกิน 0.1 วินาที ควรตรวจสอบ
# Force Sync ทันที (chrony)
sudo chronyc makestep
# Force Sync ทันที (systemd-timesyncd) — restart service
sudo systemctl restart systemd-timesyncd
# ตรวจสอบว่า VM Guest Tools รัน (VMware/KVM)
# สำหรับ VMware: open-vm-tools ต้องรันอยู่
systemctl status open-vm-tools 2>/dev/null || echo "Not VMware"
# สำหรับ KVM: ตรวจสอบ ptp_kvm
lsmod | grep ptp_kvm
# ถ้ามี: เพิ่ม /dev/ptp0 เป็น NTP Source ใน chrony
# server /dev/ptp0 poll 2 dpoll -2 offset 0
UTC vs Local Time Zone บน Server
# แนวทางการเลือก Time Zone สำหรับ Server
# แนะนำ: ตั้ง Server เป็น UTC เสมอ — Application จัดการ Time Zone เอง
# ข้อดีของ UTC บน Server:
# 1. Log มี Timestamp ที่ Consistent ไม่มีปัญหา DST (Daylight Saving)
# 2. ง่ายต่อการ Debug Log จากหลาย Server ในหลาย Time Zone
# 3. Database ที่เก็บ UTC สามารถแปลง Display Time Zone ฝั่ง Application ได้
# ตั้ง Server เป็น UTC
sudo timedatectl set-timezone UTC
# ตรวจสอบ
timedatectl
# Time zone: UTC (UTC, +0000)
# หมายเหตุ: ถ้าผู้ใช้อยู่ในประเทศไทย ให้ Application แปลง UTC → Asia/Bangkok
# ไม่ใช่ตั้ง Server เป็น Asia/Bangkok
# สคริปต์ตั้งค่า Time Zone และ NTP แบบครบวงจร
#!/bin/bash
# /usr/local/bin/setup-timezone.sh
TIMEZONE="${1:-UTC}"
echo "=== Setting up Time Zone: ${TIMEZONE} ==="
# ตั้งค่า Time Zone
timedatectl set-timezone "$TIMEZONE"
echo "Time Zone set to: $(timedatectl show --property=Timezone --value)"
# ติดตั้ง chrony ถ้ายังไม่มี
if ! command -v chronyd >/dev/null 2>&1; then
if command -v apt >/dev/null 2>&1; then
apt install -y chrony
elif command -v dnf >/dev/null 2>&1; then
dnf install -y chrony
fi
fi
# เปิดใช้งาน chrony
systemctl enable --now chronyd
# Force Sync ครั้งแรก
sleep 2
chronyc makestep
# ตั้งค่า Hardware Clock เป็น UTC
timedatectl set-local-rtc 0
hwclock --systohc
echo "=== Final Status ==="
timedatectl
chronyc tracking | grep -E "Stratum|System time|Last offset"
echo "Current time: $(date)"
สรุป
การตั้งค่า Time Zone บน Linux ใช้ timedatectl set-timezone โดยสามารถค้นหา Time Zone ที่ถูกต้องได้จาก timedatectl list-timezones แนะนำให้ตั้ง Server เป็น UTC แล้วจัดการ Time Zone ที่ Application Layer เพื่อหลีกเลี่ยงปัญหา DST และความไม่สอดคล้องใน Log การ Sync เวลาใช้ได้ทั้ง systemd-timesyncd ที่มีมากับ systemd และ chrony ที่แม่นยำกว่าสำหรับ Server จริง และต้องตั้งค่า Time Zone แยกสำหรับ PHP, Python, MySQL/PostgreSQL เพราะแต่ละ Application มี Time Zone Setting ของตัวเอง
แนะนำบริการ DE
การตั้งค่า Time Zone และ NTP บน Server ต้องการสิทธิ์ Root เพื่อรัน timedatectl และแก้ไข System Configuration Cloud VPS ของ DE ให้ Root Access เต็มรูปแบบ สามารถตั้งค่า Time Zone, NTP Server, และ chrony ได้อย่างอิสระตามความต้องการ รองรับทั้ง Ubuntu และ Rocky Linux
สำหรับผู้ที่ต้องการโฮสต์เว็บไซต์โดยไม่ต้องจัดการ System Configuration เอง Cloud Hosting ของ DE มีการตั้งค่า Time Zone และ NTP ที่พร้อมใช้งาน Log ทุกอย่างมี Timestamp ที่ถูกต้องโดยอัตโนมัติ

