Kursus Python / Mengolah tanggal dan zona waktu dengan datetime dan zoneinfo
Gunakan date untuk hari kalender dan datetime dengan informasi zona waktu ketika suatu saat tertentu perlu diidentifikasi. Bedakan nilai naive yang tidak mempunyai informasi zona dari nilai aware, lalu tentukan aturan penyimpanan dan tampilan secara jelas.
Pisahkan tanggal, durasi, dan saat tertentu
date menyatakan tahun, bulan, dan hari. datetime menggabungkan tanggal serta jam, sedangkan timedelta menyatakan durasi. Jam 09:00 di satu zona belum tentu menunjukkan saat yang sama dengan 09:00 di zona lain.
UTC adalah Coordinated Universal Time, basis waktu yang dipakai pada contoh. Nilai aware menyediakan interpretasi zona yang cukup untuk menghubungkan waktu dengan suatu saat. Nilai naive tidak menyatakan apakah jamnya berasal dari UTC, waktu lokal, atau aturan lain. Jangan menambahkan label UTC secara sembarang hanya agar operasi waktu tidak gagal.
date.fromisoformat membaca bentuk tanggal ISO yang didukung dan menolak tanggal kalender tidak sah dengan ValueError. Menambahkan 30 hari tidak sama dengan satu bulan kalender. Misalnya, kebijakan jatuh tempo dari akhir bulan harus menentukan apa yang terjadi ketika bulan tujuan tidak mempunyai tanggal yang sama. Rujukan tipe tersedia pada dokumentasi datetime Python.
Konversikan saat UTC ke waktu Seoul
Gunakan Python 3.12 atau lebih baru melalui lingkungan proyek. zoneinfo berasal dari pustaka standar, tetapi membutuhkan basis data zona IANA (Internet Assigned Numbers Authority). Ia menggunakan data sistem jika tersedia atau paket tzdata sebagai fallback.
Jika lingkungan tidak menyediakan data zona, seperti pada sebagian instalasi Windows, pasang paket resmi pada lingkungan proyek dengan python -m pip install tzdata sebelum menjalankan contoh. Jika ZoneInfoNotFoundError muncul, periksa pula ejaan nama zona. Lihat sumber data zoneinfo dan paket tzdata di PyPI.
Simpan kode lengkap sebagai dates.py dengan encoding UTF-8 dan jalankan python dates.py.
from datetime import date, datetime, timedelta, timezone
from zoneinfo import ZoneInfo
day = date.fromisoformat("2026-10-17")
print(day + timedelta(days=7))
utc = datetime(2026, 10, 17, 0, 0, tzinfo=timezone.utc)
seoul = utc.astimezone(ZoneInfo("Asia/Seoul"))
print(utc.isoformat())
print(seoul.isoformat())
Keluaran yang diharapkan:
2026-10-24
2026-10-17T00:00:00+00:00
2026-10-17T09:00:00+09:00
Bagian pertama menambahkan tujuh hari pada tanggal. Bagian kedua membuat saat 00:00 UTC dengan zona eksplisit, kemudian menampilkan saat yang sama sebagai 09:00 di Seoul pada tanggal contoh. isoformat menampilkan tanggal, jam, dan offset zona yang diketahui pada objek.
Bedakan konversi dari penggantian interpretasi zona
astimezone mempertahankan saat yang dimaksud sambil mengubah representasi jam dan zona. replace(tzinfo=...) mempertahankan angka jam, tetapi mengganti interpretasi zonanya. Keduanya tidak dapat dianggap sebagai operasi yang setara.
Simpan contoh pembanding lengkap sebagai zones.py lalu jalankan python zones.py dalam lingkungan yang sama.
from datetime import datetime, timezone
from zoneinfo import ZoneInfo
utc = datetime(2026, 10, 17, 0, 0, tzinfo=timezone.utc)
print(utc.astimezone(ZoneInfo("Asia/Seoul")).isoformat())
print(utc.replace(tzinfo=ZoneInfo("Asia/Seoul")).isoformat())
try:
print(datetime(2026, 10, 17) - utc)
except TypeError:
print("naive and aware cannot be subtracted")
Keluaran yang diharapkan:
2026-10-17T09:00:00+09:00
2026-10-17T00:00:00+09:00
naive and aware cannot be subtracted
Baris pertama tetap menunjukkan saat yang sama dengan UTC asal. Baris kedua menyatakan tengah malam Seoul, sehingga menunjukkan saat sembilan jam lebih awal daripada tengah malam UTC pada tanggal contoh. Memberi label zona berbeda tanpa mengubah jam dapat mengubah makna data, bukan sekadar tampilan.
Pengurangan naive dan aware ditolak dengan TypeError karena interpretasi kedua nilai tidak sebanding secara langsung. Telusuri asal data dan normalisasi dengan aturan yang diketahui. Jangan menganggap setiap waktu tanpa offset pasti UTC atau pasti waktu komputer yang sedang dipakai.
Di wilayah yang memakai perubahan jam musiman, jam lokal dapat ambigu atau tidak ada pada batas peralihan. Zona IANA menyimpan aturan menurut wilayah dan tanggal, sehingga lebih sesuai daripada menambahkan selisih jam secara manual untuk semua kasus. Pelihara data zona pada lingkungan yang didistribusikan karena aturan wilayah dapat berubah.
Pilih aturan penyimpanan dan uji pergantian tanggal
- Jalankan kedua program asli dan cocokkan tanggal serta offset. Pastikan sumber data zona tersedia pada interpreter yang sama dengan yang menjalankan program.
- Ubah hanya jam UTC pada program pertama dari 0 menjadi 23. Waktu UTC menjadi 2026-10-17 23:00 dan tampilan Seoul menjadi 2026-10-18 08:00, sehingga tanggalnya berganti.
- Pulihkan jam, lalu coba
date.fromisoformat("2026-02-30")sebagai pengujian terpisah. Tanggal itu ditolak, bukan otomatis disesuaikan ke bulan berikutnya. - Pulihkan seluruh sumber dan cocokkan keluaran kedua program sebelum menyimpan hasil ke aplikasi lain.
Untuk saat transaksi, pilih representasi konsisten seperti UTC atau nilai dengan offset dan lakukan konversi ketika menampilkan. Jika yang bermakna hanya tanggal pengeluaran menurut aturan bisnis, menyimpan date dapat lebih jelas daripada menciptakan jam tengah malam yang sebenarnya tidak diketahui.
String ISO yang memuat offset tidak selalu mempertahankan identitas zona wilayah dan semua aturan masa depannya. Jika aplikasi memerlukannya, simpan nama zona sebagai bagian kontrak data yang terpisah. Saat beralih ke penyimpanan JSON, tentukan pula bagaimana tanggal dan datetime diubah menjadi teks serta dibaca kembali.




