𝗔𝗣𝗜 𝗦𝗮𝘆𝗮 𝗥𝗼𝘀𝗮𝗸 𝗦𝗲𝘁𝗶𝗮𝗽 𝟭 𝗝𝗮𝗻𝘂𝗮𝗿𝗶
API saya rosak tepat pada jam 00:00 UTC pada 1 Januari.
Ia tidak rosak pada waktu tengah malam pengguna. Ia rosak pada tengah malam UTC. Pengguna di Tokyo melihat data yang rosak bermula jam 9 pagi waktu mereka.
Ujian lulus. Persekitaran staging berfungsi. Ralat hanya wujud dalam production kerana pelayan production menggunakan zon masa yang berbeza daripada staging.
Masalahnya terletak pada logik ini:
function getDailyReport(date) {
const start = new Date(date).toISOString().split('T')[0];
const end = new Date(start + 'T23:59:59Z');
return db.reports.findMany({
where: {
createdAt: { gte: new Date(start), lt: end }
}
});
}
Apabila anda memasukkan tarikh seperti "2026-01-01" tanpa masa, sistem akan menggunakan zon masa tempatan.
Pelayan staging kami menggunakan UTC. Pelayan production kami menggunakan US-East. Ini menyebabkan perbezaan (offset) lima jam pada setiap pertanyaan tarikh.
Kami kehilangan lima jam data pada setiap pertanyaan. Angka-angka tersebut kelihatan cukup hampir sehingga tiada sesiapa menyedarinya selama setahun penuh.
Penyelesaiannya mudah. Paksa UTC dengan menambah masa pada string tersebut:
function getDailyReport(date: string) {
const start = new Date(`${date}T00:00:00Z`);
const end = new Date(`${date}T23:59:59.999Z`);
return db.reports.findMany({
where: {
createdAt: { gte: start, lt: end }
}
});
}
Perubahan kod hanya mengambil masa beberapa saat. Pembaikan sistem mengambil masa seminggu. Kami melakukan empat perkara ini:
• Menambah pengesahan zon masa dalam CI untuk memastikan persekitaran kekal dalam UTC.
• Menetapkan TZ=UTC dalam semua Dockerfile untuk memastikan setiap kontena adalah serupa.
• Menambah semakan zon masa pada skrip deployment.
• Menulis peraturan linter untuk menandakan mana-mana pembina Date yang tidak mempunyai maklumat zon masa.
Pepijat zon masa adalah berbahaya. Ia tidak menyebabkan sistem anda terhenti. Ia menghasilkan data salah yang kelihatan betul. Pengguna anda tidak akan melihat halaman ralat. Mereka akan melihat angka yang tidak tepat dan mereka akan mempercayainya.
Ikuti tiga peraturan ini:
- Jangan sesekali mempercayai zon masa sistem. Sentiasa tetapkan TZ=UTC.
- Jangan sesekali mencerakin (parse) tarikh tanpa zon masa.
- Jangan sesekali menganggap zon masa CI anda sama dengan production.