Satu momen di dunia ini memiliki banyak penampilan: 10:30 di Jakarta adalah 03:30 di UTC. Praktik yang lazim menyarankan penyimpanan dan pertukaran data dalam UTC, lalu konversi ke waktu lokal hanya pada lapisan tampilan. Konversi di .NET memiliki dua jalur: ToLocalTime dan ToUniversalTime yang mengikuti zona mesin, atau TimeZoneInfo.ConvertTimeToUtc dan ConvertTimeFromUtc yang memakai zona eksplisit pilihan kita.
Konversi dengan Zona Eksplisit #
TimeZoneInfo jakarta = TimeZoneInfo.FindSystemTimeZoneById("Asia/Jakarta");
DateTime lokal = new DateTime(2025, 8, 17, 10, 30, 0, DateTimeKind.Unspecified);
DateTime utc = TimeZoneInfo.ConvertTimeToUtc(lokal, jakarta);
Console.WriteLine(utc.ToString("yyyy-MM-dd HH:mm 'UTC'", CultureInfo.InvariantCulture));
Console.WriteLine(utc.Kind);
DateTime kembali = TimeZoneInfo.ConvertTimeFromUtc(utc, jakarta);
Console.WriteLine(kembali.ToString("yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture));Output yang Dihasilkan:
2025-08-17 03:30 UTC
Utc
2025-08-17 10:30Mari kita bedah baris demi baris:
- Baris 3 (
DateTimeKind.Unspecified): nilai 10:30 dinyatakan tanpa zona; artinya angka tersebut dianggap milik zona yang kita kirim pada langkah berikutnya. - Baris 5 (
ConvertTimeToUtc(lokal, jakarta)): runtime mengurangi offset 7 jam dan menghasilkan03:30; propertiKindhasil konversi otomatis menjadiUtc. - Baris 8 (
ConvertTimeFromUtc): konversi balik mengembalikan10:30dengan arah yang seimbang, membuktikan round-trip zona berjalan utuh. - Format
'UTC': tanda kutip tunggal pada pola format mencetak teksUTCsebagai literal, bukan penentu format.
Aturan praktisnya dapat dirangkum tiga langkah: terima payload lengkap dengan offset atau DateTimeOffset, simpan sebagai UTC, lalu konversi ke zona pengguna hanya saat menampilkan. Dengan pola tersebut, data historis tetap akurat meski aturan zona berubah, dan dua server di zona berbeda tidak pernah menyimpan waktu yang saling bertentangan.