Untuk mengubah tanggal publikasi dan zona waktu bernama menjadi waktu tengah malam yang tepat, tentukan waktu lokal 00:00:00 menggunakan aturan zona tersebut, periksa apakah waktu itu ada, lalu konversikan ke UTC. Alur kerja Terminal Mac ini juga mendeteksi tengah malam yang berulang.
Misalkan sebuah catatan publikasi sintetis berisi tanggal 2025-07-15 dan zona America/New_York. Tugas Anda adalah menghitung stempel waktu yang mewakili tengah malam pada awal tanggal tersebut. Alur kerja di bawah ini menghasilkan stempel waktu yang dapat Anda salin ke alat yang menerima UTC, sambil tetap menampilkan tanggal dan zona asli untuk diperiksa.
Informasi apa yang menentukan waktu tengah malam?
Pisahkan keempat nilai ini sepanjang perhitungan:
| Nilai | Contoh sintetis | Arti |
|---|---|---|
| Tanggal sipil | 2025-07-15 |
Tanggal kalender Gregorian tanpa waktu atau zona |
| Tanggal dan waktu lokal | 2025-07-15T00:00:00 |
Waktu yang ditunjukkan oleh jam dinding yang diminta |
| Zona waktu bernama | America/New_York |
Aturan untuk menafsirkan waktu lokal tersebut |
| Waktu yang ditentukan | 2025-07-15T04:00:00Z |
Satu momen tertentu yang dinyatakan dalam UTC |
Python merepresentasikan tanggal kalender dengan date, menggabungkan kolom tanggal dan waktu dengan datetime, serta menggunakan informasi zona waktu untuk menafsirkan objek datetime yang sadar zona. Kelas timezone merepresentasikan offset tetap; zoneinfo menyediakan aturan zona bernama. Lihat dokumentasi datetime dan dokumentasi zoneinfo resmi.
Offset seperti -04:00 adalah selisih antara waktu lokal dan UTC untuk pembacaan waktu tertentu. Zona bernama menyediakan aturan yang dapat menghasilkan offset berbeda pada tanggal berbeda. RFC 9557 menjelaskan mengapa mengganti zona bernama dengan offset tetap dapat menghasilkan perhitungan lanjutan yang keliru. Pertahankan nama zona, alih-alih menyalin offset dari catatan publikasi lain. RFC 9557: Tanggal dan Waktu di Internet: Stempel Waktu dengan Informasi Tambahan
Untuk tugas ini, “tengah malam” berarti tepat 00:00:00 pada awal tanggal yang diberikan. Nyatakan persyaratan itu dengan jelas sebelum menghitung apa pun: permintaan untuk momen valid pertama suatu hari kalender memerlukan kebijakan berbeda jika tengah malam tidak ada.
Mengapa tengah malam harus diperiksa sebelum konversi?
Perubahan jam lokal dapat menimbulkan celah, yaitu waktu pada jam dinding yang tidak terjadi, atau lipatan, yaitu waktu yang terjadi dua kali. PEP 495 Python mendefinisikan kasus-kasus ini dan menyediakan atribut fold untuk membedakan pembacaan waktu yang berulang. PEP tersebut juga mendokumentasikan bahwa konstruktor dan replace() tidak otomatis menolak waktu lokal yang tidak ada. Karena itu, menambahkan zona saja tidak memvalidasi tengah malam yang diminta. PEP 495 – Disambiguasi Waktu Lokal
Gunakan aturan keputusan berikut untuk persyaratan publikasi yang mengharuskan tepat tengah malam:
| Jumlah waktu tengah malam valid yang ditemukan | Interpretasi | Tindakan |
|---|---|---|
| Satu | Tengah malam unik | Kembalikan waktu tersebut |
| Dua | Tengah malam berulang | Tolak sampai kebijakan lebih awal/lebih akhir dipilih |
| Tidak ada | Tepat tengah malam tidak ada | Laporkan bahwa persyaratan tidak dapat dipenuhi dengan masukan tersebut |
Program di bawah menerapkan aturan ini dengan mencoba kedua nilai fold, mengonversi setiap kandidat ke UTC, lalu mengonversinya kembali ke zona bernama. Kandidat hanya dipertahankan jika kolom lokal yang dikembalikan sama persis dengan tengah malam yang diminta. Hasil UTC yang duplikat digabungkan menjadi satu kandidat. Urutan validasi ini diturunkan dari perilaku konversi dan fold yang didokumentasikan; ini merupakan logika tambahan pada aplikasi. datetime.astimezone(), PEP 495
Bagaimana menjalankan perhitungan di Terminal Mac?
Buka Spotlight, ketik Terminal, lalu buka aplikasinya. Cara lain, buka /Applications/Utilities di Finder, lalu klik dua kali Terminal. Keduanya adalah cara membuka jendela perintah yang didokumentasikan Apple. Membuka atau menutup Terminal di Mac
Jalankan perintah berikut untuk memeriksa versi Python Anda:
python3 --version
Contoh ini memerlukan Python 3.9 atau yang lebih baru, saat zoneinfo mulai tersedia. Jika Python tidak ada atau versinya lebih lama, ikuti panduan instalasi macOS resmi untuk mendapatkan penginstal Python yang saat ini didukung dari Python.org, lalu ulangi pemeriksaan versi. Alur kerja ini menggunakan modul pustaka standar. zoneinfo — Dukungan zona waktu IANA, Menggunakan Python di macOS
Salin seluruh blok di bawah ini ke Terminal dan tekan Return. Ini adalah perintah lengkap yang berisi program Python. Untuk menghitung stempel waktu publikasi lain, ubah DATE_TEXT dan ZONE_NAME sebelum menempelkan perintah. Biarkan REPEATED sebagai reject kecuali Anda sengaja telah memilih kebijakan untuk tengah malam yang berulang.
python3 - <<'PY'
from datetime import date, datetime, time, timezone
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
DATE_TEXT = '2025-07-15'
ZONE_NAME = 'America/New_York'
REPEATED = 'reject' # 'reject', 'earlier', or 'later'
def resolve_midnight(date_text, zone_name, repeated='reject'):
if repeated not in {'reject', 'earlier', 'later'}:
raise ValueError('Repeated-time policy must be reject, earlier, or later.')
day = date.fromisoformat(date_text)
if day.isoformat() != date_text:
raise ValueError('Use a date in YYYY-MM-DD format.')
zone = ZoneInfo(zone_name)
wall = datetime.combine(day, time.min)
candidates = set()
for fold in (0, 1):
guess = wall.replace(tzinfo=zone, fold=fold)
instant = guess.astimezone(timezone.utc)
back = instant.astimezone(zone)
if back.replace(tzinfo=None) == wall:
candidates.add(instant)
ordered = sorted(candidates)
if not ordered:
raise ValueError('Exact midnight does not exist on this date in this zone.')
if len(ordered) == 2 and repeated == 'reject':
choices = ', '.join(x.isoformat() for x in ordered)
raise ValueError(
'Midnight repeats. Choose earlier or later. UTC choices: ' + choices
)
chosen = ordered[-1] if repeated == 'later' else ordered[0]
return chosen.astimezone(zone), chosen
try:
local, utc = resolve_midnight(DATE_TEXT, ZONE_NAME, REPEATED)
except ZoneInfoNotFoundError:
raise SystemExit(
'Zone not found. Check the IANA name and time zone data installation.'
)
except (ValueError, OverflowError) as exc:
raise SystemExit(str(exc))
print('Civil date:', DATE_TEXT)
print('Named zone:', ZONE_NAME)
print('Local midnight:', local.isoformat())
print('UTC instant:', utc.isoformat().replace('+00:00', 'Z'))
PY
Untuk contoh yang diberikan, hasilnya adalah:
Civil date: 2025-07-15
Named zone: America/New_York
Local midnight: 2025-07-15T00:00:00-04:00
UTC instant: 2025-07-15T04:00:00Z
Baca kedua baris stempel waktu tersebut secara bersamaan. Baris lokal memastikan bahwa waktu pada jam dinding yang diminta adalah tengah malam. Baris UTC menunjukkan momen yang sama: mengurangi offset lokal sebesar negatif empat jam menghasilkan 04:00:00 UTC. RFC 3339 mendefinisikan stempel waktu menggunakan tanggal, waktu, dan offset numerik atau Z. RFC 3339: Tanggal dan Waktu di Internet: Stempel Waktu
Bagaimana cara memeriksa hasil biasa dan pengecualian?
Masukan berikut adalah contoh publikasi sintetis yang dipilih untuk menguji program. Hasilnya dihitung dengan resolver di atas menggunakan basis data zona waktu yang tersedia; hasil ini bukan catatan publikasi sungguhan. Ubah kedua nilai masukan dan jalankan kembali seluruh perintah untuk setiap kasus.
| Tanggal | Zona bernama | Hasil resolver |
|---|---|---|
2025-01-15 |
America/New_York |
Satu waktu: 2025-01-15T05:00:00Z |
2025-07-15 |
America/New_York |
Satu waktu: 2025-07-15T04:00:00Z |
2018-11-04 |
America/Sao_Paulo |
Tepat tengah malam tidak ada; ditolak |
2020-11-01 |
America/Havana |
Tengah malam berulang; secara default ditolak |
2011-12-30 |
Pacific/Apia |
Tepat tengah malam tidak ada; ditolak |
Dua baris pertama menunjukkan mengapa tanggal perlu disertakan dalam perhitungan: zona bernama yang sama menentukan tengah malam pada jam UTC yang berbeda. Untuk contoh Havana yang berulang, menetapkan REPEATED = 'earlier' akan memilih 2020-11-01T04:00:00Z; menetapkannya ke later akan memilih 2020-11-01T05:00:00Z. Nama tersebut merujuk pada urutan kronologis di linimasa UTC.
Hasil tengah malam yang tidak ada memerlukan keputusan tentang persyaratan publikasi. Jika tengah malam tepat sangat penting, pilih tanggal atau zona lain secara eksplisit. Jika yang dimaksud adalah waktu valid pertama pada tanggal tersebut, definisikan dan implementasikan operasi itu secara terpisah, termasuk tindakan saat seluruh tanggal tidak ada. Resolver ini sengaja melaporkan kegagalan alih-alih diam-diam mengganti waktu lokal dengan waktu lain.
Apa yang harus dilakukan jika masukan gagal?
Untuk kesalahan tanggal, masukkan tanggal Gregorian yang valid dalam format YYYY-MM-DD, seperti 2025-07-15. Program memeriksa validitas kalender sekaligus kesesuaian dengan format tersebut. Masukan seperti 2025-02-30 akan gagal, alih-alih dialihkan ke bulan berikutnya.
Untuk Zone not found, periksa pengenal IANA lengkap, termasuk ejaan dan penggunaan huruf besar-kecil. Python mendokumentasikan bahwa pengecualian ini dapat berarti kunci tidak valid atau data zona waktu tidak tersedia. Pencarian standar Python menggunakan data sistem terlebih dahulu dan paket pihak pertama tzdata sebagai cadangan. Jika datanya tidak ada, instal paket tersebut ke lingkungan Python yang Anda gunakan, lalu jalankan kembali resolver. PEP 615 – Dukungan untuk Basis Data Zona Waktu IANA di Pustaka Standar
Simpan tanggal asli, nama zona, pilihan untuk waktu berulang, dan stempel waktu UTC hasil perhitungan bersama dalam catatan kerja Anda. Jika perhitungan berbeda antarkomputer, bandingkan sumber data zona waktunya. Memasang paket cadangan tidak otomatis menggantikan data sistem yang sudah ditemukan Python. Sumber data zoneinfo
Nilai mana yang harus disalin ke alat lain?
Jika tujuan menerima stempel waktu UTC, salin nilai UTC instant, termasuk Z-nya. Pastikan format masukan yang didokumentasikan tujuan sebelum memasukkannya. Kolom tanggal biasa tidak dapat mempertahankan semua informasi yang diwakili stempel waktu hasil perhitungan tersebut; simpan tanggal asli dan zona bernama bersamanya jika Anda perlu mempertahankan maksud penjadwalan.
RFC 9557 mendefinisikan format stempel waktu diperluas yang dapat menyertakan akhiran zona bernama, tetapi format tersebut tetap merepresentasikan waktu yang telah ditentukan. RFC itu juga mengakui bahwa pembaruan data zona dapat menimbulkan inkonsistensi antara offset tersimpan dan informasi zona. Gunakan representasi diperluas hanya jika alat penerima mendokumentasikan dukungannya. RFC 9557, cakupan dan offset yang tidak konsisten
Akhiri dengan memeriksa bahwa keluaran lokal menunjukkan tanggal yang Anda maksud pada 00:00:00, nama zona sesuai dengan masukan, dan pilihan untuk tengah malam berulang memang disengaja. Setelah semua pemeriksaan tersebut lolos, keluaran UTC adalah waktu tengah malam hasil penentuan berdasarkan aturan yang digunakan dalam perhitungan itu.
Sumber
- Membuka atau menutup Terminal di Mac — Apple
- Menggunakan Python di macOS — Python Software Foundation
- datetime — Tipe dasar tanggal dan waktu — Python Software Foundation
- zoneinfo — Dukungan zona waktu IANA — Python Software Foundation
- PEP 495 – Disambiguasi Waktu Lokal — Python Software Foundation
- PEP 615 – Dukungan untuk Basis Data Zona Waktu IANA di Pustaka Standar — Python Software Foundation
- RFC 3339: Tanggal dan Waktu di Internet: Stempel Waktu — RFC Editor
- RFC 9557: Tanggal dan Waktu di Internet: Stempel Waktu dengan Informasi Tambahan — RFC Editor