API Saya Rusak Setiap 1 Januari
API saya rusak tepat pada pukul 00:00 UTC pada tanggal 1 Januari.
Ini tidak rusak pada tengah malam waktu pengguna. Ini rusak pada tengah malam UTC. Pengguna di Tokyo melihat data yang rusak mulai pukul 9 pagi waktu mereka.
Pengujian berhasil. Lingkungan staging berfungsi dengan baik. Kesalahan hanya terjadi di produksi karena server produksi menggunakan zona waktu yang berbeda dari staging.
Masalahnya terletak pada logika 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 }
}
});
}
Saat Anda memasukkan tanggal seperti "2026-01-01" tanpa waktu, sistem akan menggunakan zona waktu lokal.
Server staging kami menggunakan UTC. Server produksi kami menggunakan US-East. Hal ini menyebabkan selisih lima jam pada setiap kueri tanggal.
Kami kehilangan data selama lima jam pada setiap kueri. Angkanya terlihat cukup mendekati sehingga tidak ada yang menyadarinya selama setahun penuh.
Perbaikannya sederhana. Paksa penggunaan UTC dengan menambahkan waktu ke dalam string:
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 kode hanya memakan waktu beberapa detik. Perbaikan sistem memakan waktu seminggu. Kami melakukan empat hal berikut:
• Menambahkan asersi zona waktu di CI untuk memastikan lingkungan tetap dalam UTC.
• Mengatur TZ=UTC di semua Dockerfile agar setiap kontainer tetap identik.
• Menambahkan pemeriksaan zona waktu pada skrip deployment.
• Menulis aturan linter untuk menandai konstruktor Date apa pun yang tidak memiliki informasi zona waktu.
Bug zona waktu itu berbahaya. Mereka tidak membuat sistem Anda crash. Mereka menghasilkan data salah yang terlihat benar. Pengguna Anda tidak akan melihat halaman error. Mereka akan melihat angka yang salah dan mereka akan mempercayainya.
Ikuti tiga aturan ini:
- Jangan pernah percaya pada zona waktu sistem. Selalu atur TZ=UTC.
- Jangan pernah melakukan parsing tanggal tanpa zona waktu.
- Jangan pernah berasumsi zona waktu CI Anda sama dengan produksi.