Zona Waktu Adalah Palsu (Dan Cara Mengelolanya Dalam Kode)
Zona waktu terlihat sederhana pada peta. Tapi sebenarnya tidak. Berikut alasannya mengapa zona waktu memecah perangkat lunak — dan model pikiran yang tepat untuk mengelolanya dalam kode.
Anda membuka peta. Anda melihat potongan vertikal. 'UTC-5 adalah waktu utara, UTC+1 adalah waktu tengah Eropa.' Sederhana, kan?
Salah. Zona waktu adalah konstruksi politik, bukan fakta geografis — dan perbedaan ini akan melindungi Anda dari beberapa bug paling buruk dalam pengembangan perangkat lunak.
Mengapa Zona Waktu Sebenarnya Adalah Kacau
Berikut ini yang ditangani secara diam-diam oleh database zona waktu sistem operasi Anda:
- Pergantian Waktu (DST) — Tidak semua negara mengobservasi hal ini, negara-negara mengubah aturan mereka, dan perpindahan terjadi pada tanggal yang berbeda tergantung pada lokasi Anda. Amerika Serikat mengubah tanggalnya pada tahun 2007. Mesir menghapus DST pada tahun 2011, lalu mengembalikannya, lalu menghapusnya kembali.
- Offset setengah jam dan perempat jam — India (UTC+5:30), Nepal (UTC+5:45), dan bagian dari Australia (UTC+9:30) ada. Asumsi Anda bahwa offset adalah jam bulat adalah salah.
- Perubahan sejarah — Rusia berpindah dari UTC+4 ke UTC+3 pada tahun 2014. Samoa melewatkan satu hari penuh (30 Desember 2011) untuk berpindah dari satu sisi garis tanggal internasional ke sisi lain. Saat Anda berurusan dengan timestamp sejarah, offset yang benar bisa benar-benar berbeda dari hari ini.
- Waktu yang ambigu — Saat jam dikembalikan, 1:30 pagi terjadi dua kali. Saat jam dipercepat, 2:30 pagi sama sekali tidak ada. Jika Anda menyimpan '3 November 2024 pukul 1:45 pagi waktu utara' tanpa offset UTC, Anda memiliki timestamp yang ambigu.
Hal ini bukan hanya trivia. Setiap kasus ekstrem ini telah menyebabkan bug produksi nyata — kehilangan acara kalender, pembayaran yang dua kali, sistem jadwal yang rusak.
Aturan Satu yang Memperbaiki Sebagian Besar Masalah
Simpan dan proses dalam UTC. Konversi ke waktu lokal hanya saat tampilan.
Ini bukan saran yang kontroversial. Ini adalah kesepakatan dari setiap database besar, standar API, dan tim sistem terdistribusi. Jika kolom database Anda menyimpan 2024-11-03 06:45:00 dalam UTC, Anda selalu tahu secara tepat saat apa yang diwakili — terlepas dari lokasi server Anda, zona waktu pengguna Anda, atau apakah DST terjadi pada hari tersebut.
Momen Anda menyimpan 2024-11-03 01:45:00 tanpa offset UTC, Anda telah kehilangan informasi. Anda telah menciptakan timestamp yang berarti dua hal yang berbeda.
Cara Menangani Zona Waktu dalam JavaScript
Objek bawaan JavaScript menyimpan waktu sebagai milidetik sejak epoch Unix (1 Januari 1970 UTC) — yang baik. Masalahnya adalah bahwa antarmukanya membingungkan dan tidak konsisten. Date objek menyimpan waktu sebagai milidetik sejak epoch Unix (1 Januari 1970 UTC) — yang bagus. Masalahnya adalah bahwa antarmukanya membingungkan dan tidak konsisten.
Apa yang harus dihindari
// BAD: Parsing without explicit timezone
const d = new Date('2024-11-03 01:45:00');
// Interpreted as LOCAL time — behavior varies by environment
// BAD: Storing user-facing strings as dates
const meeting = '3:00 PM Thursday';
// This is meaningless without a timezone
Apa yang harus digunakan sebagai gantinya
// GOOD: Always use ISO 8601 with explicit UTC offset
const d = new Date('2024-11-03T06:45:00Z'); // Z = UTC
// GOOD: Display in user's local timezone using Intl API
const formatter = new Intl.DateTimeFormat('en-US', {
timeZone: 'America/New_York',
dateStyle: 'full',
timeStyle: 'short',
});
console.log(formatter.format(d)); // "Sunday, November 3, 2024 at 1:45 AM"
Jika Anda membuat sesuatu di luar format tanggal sederhana, gunakan adalah pilihan lain yang kuat. Moment.js sudah lengkap fitur tetapi tidak lagi dijaga — pindahlah dari itu. pustaka. Ini memiliki dukungan zona waktu kelas pertama, menangani transisi DST secara benar, dan membuat niat kode Anda jelas.
import { DateTime } from 'luxon';
// Parse an ISO string and convert to a specific zone
const utc = DateTime.fromISO('2024-11-03T06:45:00Z');
const eastern = utc.setZone('America/New_York');
console.log(eastern.toLocaleString(DateTime.DATETIME_FULL));
// "November 3, 2024, 1:45 AM EDT"
Cara Menangani Zona Waktu dalam Python
membedakan antara “datetime tidak sadar” (tidak memiliki informasi zona waktu) dan “datetime sadar” (dengan tzinfo). Datetime tidak sadar adalah penipuan — mereka terlihat valid tetapi tidak memiliki makna di antara sistem. datetime modul membedakan antara tidak sadar (tanpa zona waktu) dan sadar (dengan zona waktu) objek waktu. Waktu tidak sadar adalah perangkap — hindari mereka dalam kode yang melintasi batas zona waktu.
from datetime import datetime, timezone
import zoneinfo # Python 3.9+
# BAD: naive datetime (no timezone info)
d = datetime(2024, 11, 3, 1, 45, 0)
# GOOD: always attach a timezone
d_utc = datetime(2024, 11, 3, 6, 45, 0, tzinfo=timezone.utc)
# Convert to a specific timezone
eastern = zoneinfo.ZoneInfo('America/New_York')
d_eastern = d_utc.astimezone(eastern)
print(d_eastern) # 2024-11-03 01:45:00-05:00
Untuk Python yang lebih tua atau kebutuhan penjadwalan yang lebih kompleks, python-dateutil dan Panah adalah pilihan yang terus diperbaiki. Prinsip utama tetap sama: kerjakan dalam UTC, konversi di batas.
Cara Menangani Zona Waktu dalam Database
Pengelolaan zona waktu dalam database membingungkan bahkan para pengembang berpengalaman.
PostgreSQL
PostgreSQL memiliki dua jenis timestamp: timestamp (tanpa zona waktu) dan timestamptz (dengan zona waktu). Meskipun namanya, timestamptz tidak menyimpan zona waktu — ia dikonversi ke UTC saat ditulis dan dikonversi kembali ke zona waktu sesi saat dibaca. Ini adalah perilaku yang benar. Selalu gunakan timestamptz.
-- BAD
CREATE TABLE events (created_at TIMESTAMP);
-- GOOD
CREATE TABLE events (created_at TIMESTAMPTZ);
-- Querying across timezones
SELECT created_at AT TIME ZONE 'America/New_York' FROM events;
MySQL
MySQL’s DATETIME yang menyimpan tanpa konteks zona waktu — apa yang Anda masukkan adalah apa yang Anda dapatkan, tanpa konversi. TIMESTAMP konversi ke UTC saat ditulis dan kembali ke zona waktu server saat dibaca — tetapi terbatas pada tanggal antara 1970 dan 2038 (overflow timestamp Unix). Dalam praktiknya: gunakan DATETIME kolom dan pastikan aplikasi Anda selalu menulis nilai UTC secara eksplisit.
Penjadwalan di Berbagai Zona Waktu: Penyimpangan Tersembunyi
Misalnya, pengguna menjadwalkan pertemuan mingguan berulang untuk 'setiap hari Senin pukul 9 pagi waktu New York'. Anda menyimpan kejadian berikutnya sebagai timestamp UTC. Baik — sampai perubahan DST, dan sekarang waktu UTC yang Anda simpan berarti pukul 10 pagi di New York alih-alih pukul 9 pagi.
Solusi: jangan menyimpan timestamp absolut untuk kejadian berulang. Simpan aturan lokal — identifikasi zona waktu + waktu lokal — dan hitung timestamp UTC berikutnya secara dinamis. Dengan cara ini, sistem menghitung kembali secara benar setelah transisi DST.
-- Store the intent, not the absolute moment
CREATE TABLE recurring_events (
id SERIAL PRIMARY KEY,
timezone TEXT NOT NULL, -- 'America/New_York'
local_time TIME NOT NULL, -- '09:00:00'
recurrence TEXT NOT NULL -- 'WEEKLY:MONDAY'
);
-- Compute next_occurrence_utc in application code at dispatch time
Nama Zona Waktu IANA dibandingkan dengan Offset UTC
Ketika menyimpan preferensi zona waktu pengguna, simpan nama zona waktu IANA (America/New_York, Europe/London, Asia/Kolkata) — bukan offset UTC (UTC-5, UTC+1). Offset adalah snapshot; nama zona waktu IANA mengkodekan sejarah DST dan aturan masa depan.
America/New_York adalah UTC-5 di musim dingin dan UTC-4 di musim panas. Jika Anda menyimpan UTC-5, Anda memasukkan offset yang salah setengah tahunnya.
Referensi Cepat: Aturan
- Simpan timestamp dalam UTC — selalu, tanpa pengecualian dalam database atau respons API.
- Gunakan nama zona waktu IANA — bukan offset UTC — untuk preferensi pengguna dan penjadwalan berulang.
- Jangan memarsing string tanggal tanpa zona waktu eksplisit — perilaku implisit bergantung pada lingkungan.
- Konversi ke waktu lokal hanya di lapisan tampilan — bukan di logika bisnis atau query database.
- Untuk penjadwalan berulang, simpan aturan — bukan waktu UTC yang dihitung sebelumnya — agar transisi DST tidak merusak kejadian di masa depan.
- Uji dengan kasus ekstrem — jam transisi DST, tanggal dekat garis tanggal internasional, dan timestamp sejarah di wilayah yang telah mengubah offset mereka.
Instal Ekstensi Kami
Tambahkan alat IO ke browser favorit Anda untuk akses instan dan pencarian lebih cepat
恵 Papan Skor Telah Tiba!
Papan Skor adalah cara yang menyenangkan untuk melacak permainan Anda, semua data disimpan di browser Anda. Lebih banyak fitur akan segera hadir!
Alat Wajib Coba
Lihat semua Pendatang baru
Lihat semuaMemperbarui: Kita alat terbaru ditambahkan pada 15 Juni 2026
