Untuk menukar tarikh penerbitan dan zon waktu bernama kepada detik tengah malam yang tepat, tentukan waktu tempatan 00:00:00 menggunakan peraturan zon tersebut, semak sama ada waktu itu wujud, kemudian tukarkannya kepada UTC. Aliran kerja Terminal Mac ini juga mengesan tengah malam yang berulang.
Katakan rekod penerbitan sintetik mengandungi tarikh 2025-07-15 dan zon America/New_York. Tugas anda ialah mengira cap masa yang mewakili tengah malam pada permulaan tarikh tersebut. Aliran kerja di bawah menghasilkan cap masa yang boleh anda salin ke alat yang menerima UTC, sambil mengekalkan tarikh dan zon asal supaya mudah disemak.
Apakah maklumat yang mentakrifkan detik tengah malam?
Pastikan empat nilai ini berasingan sepanjang pengiraan:
| Nilai | Contoh sintetik | Maksud |
|---|---|---|
| Tarikh sivil | 2025-07-15 |
Tarikh kalendar Gregorian tanpa waktu atau zon |
| Tarikh dan waktu tempatan | 2025-07-15T00:00:00 |
Bacaan jam dinding yang diminta |
| Zon waktu bernama | America/New_York |
Peraturan yang digunakan untuk mentafsir bacaan tempatan itu |
| Detik yang ditentukan | 2025-07-15T04:00:00Z |
Satu detik khusus yang dinyatakan dalam UTC |
Python mewakili tarikh kalendar dengan date, menggabungkan medan tarikh dan waktu dengan datetime, dan menggunakan maklumat zon waktu untuk mentafsir datetime yang sedar zon. Kelas timezone mewakili ofset tetap; zoneinfo menyediakan peraturan zon bernama. Lihat dokumentasi datetime dan dokumentasi zoneinfo rasmi.
Ofset seperti -04:00 ialah perbezaan antara waktu tempatan dengan UTC bagi bacaan tertentu. Zon bernama menyediakan peraturan yang boleh menghasilkan ofset berbeza pada tarikh berlainan. RFC 9557 menerangkan sebab penggantian zon bernama dengan ofset tetap boleh menghasilkan pengiraan seterusnya yang salah. Kekalkan nama zon dan bukannya menyalin ofset daripada rekod penerbitan lain. RFC 9557: Tarikh dan Waktu di Internet: Cap Masa dengan Maklumat Tambahan
Untuk tugas ini, “tengah malam” bermaksud tepat 00:00:00 pada permulaan tarikh yang diberikan. Nyatakan keperluan itu dengan jelas sebelum membuat sebarang pengiraan: permintaan untuk detik pertama yang sah dalam sesuatu hari kalendar memerlukan dasar yang berbeza apabila tengah malam tiada.
Mengapakah tengah malam perlu disemak sebelum penukaran?
Perubahan jam tempatan boleh mewujudkan jurang, apabila bacaan jam dinding tidak berlaku, atau lipatan, apabila bacaan itu berlaku dua kali. PEP 495 Python mentakrifkan kes ini dan menyediakan atribut fold untuk membezakan bacaan berulang. PEP itu juga mendokumenkan bahawa pembina dan replace() tidak menolak waktu tempatan yang tiada secara automatik. Oleh itu, melampirkan zon sahaja tidak mengesahkan tengah malam yang diminta. PEP 495 – Pembezaan Waktu Tempatan
Gunakan peraturan keputusan berikut untuk keperluan penerbitan yang menetapkan tengah malam tepat:
| Bilangan detik tengah malam yang sah ditemui | Tafsiran | Tindakan |
|---|---|---|
| Satu | Tengah malam adalah unik | Pulangkan detik itu |
| Dua | Tengah malam berulang | Tolak sehingga dasar lebih awal/lebih lewat dipilih |
| Tiada | Tengah malam tepat tiada | Laporkan bahawa keperluan itu tidak dapat dipenuhi dengan input tersebut |
Program di bawah melaksanakan peraturan ini dengan mencuba kedua-dua nilai fold, menukar setiap calon kepada UTC, kemudian menukarnya semula kepada zon bernama. Calon hanya diterima jika medan tempatannya selepas penukaran sepadan tepat dengan tengah malam yang diminta. Hasil UTC yang pendua digabungkan menjadi satu calon. Urutan pengesahan ini berasaskan tingkah laku penukaran dan fold yang didokumenkan; ini ialah logik aplikasi tambahan. datetime.astimezone(), PEP 495
Bagaimanakah anda menjalankan pengiraan dalam Terminal Mac?
Buka Spotlight, taip Terminal, kemudian buka aplikasi itu. Sebagai alternatif, buka /Applications/Utilities dalam Finder dan klik dua kali Terminal. Ini ialah cara yang didokumenkan oleh Apple untuk membuka tetingkap arahan. Buka atau keluar daripada Terminal pada Mac
Jalankan arahan berikut untuk menyemak versi Python anda:
python3 --version
Contoh ini memerlukan Python 3.9 atau lebih baharu, iaitu versi yang mula menyediakan zoneinfo. Jika Python tiada atau versinya lebih lama, ikut panduan pemasangan macOS rasmi untuk mendapatkan pemasang Python yang masih disokong daripada Python.org, kemudian ulangi semakan versi. Aliran kerja ini menggunakan modul pustaka standard. zoneinfo — Sokongan zon waktu IANA, Menggunakan Python pada macOS
Salin keseluruhan blok di bawah ke dalam Terminal dan tekan Return. Blok ini ialah arahan lengkap yang mengandungi program Python. Untuk mengira cap masa penerbitan yang lain, edit DATE_TEXT dan ZONE_NAME sebelum menampalnya. Kekalkan REPEATED sebagai reject melainkan anda sengaja memilih dasar 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
Bagi sampel yang diberikan, hasilnya ialah:
Tarikh sivil: 2025-07-15
Zon bernama: America/New_York
Tengah malam tempatan: 2025-07-15T00:00:00-04:00
Detik UTC: 2025-07-15T04:00:00Z
Baca kedua-dua baris cap masa bersama-sama. Baris tempatan mengesahkan bahawa waktu jam dinding yang diminta ialah tengah malam. Baris UTC mengenal pasti detik yang sama: menolak ofset tempatan negatif empat jam menghasilkan 04:00:00 UTC. RFC 3339 mentakrifkan cap masa menggunakan tarikh, waktu dan sama ada ofset berangka atau Z. RFC 3339: Tarikh dan Waktu di Internet: Cap Masa
Bagaimanakah anda menyemak hasil biasa dan luar biasa?
Input berikut ialah contoh penerbitan sintetik yang dipilih untuk menguji program. Hasilnya dikira menggunakan penyelesai di atas dengan pangkalan data zon waktu yang tersedia; hasil ini bukan rekod penerbitan sebenar. Tukar kedua-dua nilai input dan jalankan semula arahan lengkap bagi setiap kes.
| Tarikh | Zon bernama | Hasil penyelesai |
|---|---|---|
2025-01-15 |
America/New_York |
Satu detik: 2025-01-15T05:00:00Z |
2025-07-15 |
America/New_York |
Satu detik: 2025-07-15T04:00:00Z |
2018-11-04 |
America/Sao_Paulo |
Tengah malam tepat tiada; ditolak |
2020-11-01 |
America/Havana |
Tengah malam berulang; ditolak secara lalai |
2011-12-30 |
Pacific/Apia |
Tengah malam tepat tiada; ditolak |
Dua baris pertama menunjukkan sebab tarikh perlu disertakan dalam pengiraan: zon bernama yang sama menentukan waktu UTC yang berbeza untuk tengah malam. Bagi contoh Havana yang berulang, menetapkan REPEATED = 'earlier' memilih 2020-11-01T04:00:00Z; menetapkannya kepada later memilih 2020-11-01T05:00:00Z. Nama tersebut merujuk kepada tertib kronologi pada garis masa UTC.
Hasil tengah malam tiada memerlukan keputusan tentang keperluan penerbitan. Jika tengah malam tepat penting, pilih tarikh atau zon lain secara jelas. Jika keperluan yang dimaksudkan ialah waktu sah pertama pada tarikh itu, takrifkan dan laksanakan operasi tersebut secara berasingan, termasuk tindakan apabila keseluruhan tarikh itu tiada. Penyelesai ini sengaja melaporkan kegagalan dan bukannya menggantikan waktu tempatan secara senyap.
Apakah yang perlu dilakukan apabila input gagal?
Jika terdapat ralat tarikh, masukkan tarikh Gregorian yang sah dalam format YYYY-MM-DD, seperti 2025-07-15. Program ini menyemak kesahihan kalendar serta format tepat tersebut. Input seperti 2025-02-30 gagal dan tidak diteruskan ke bulan berikutnya.
Bagi Zone not found, semak pengecam IANA lengkap, termasuk ejaan dan huruf besar atau kecil. Python mendokumenkan bahawa pengecualian ini boleh bermaksud kunci tidak sah atau data zon waktu tidak tersedia. Carian standardnya menggunakan data sistem dahulu dan pakej pihak pertama tzdata sebagai sandaran. Jika data tiada, pasang pakej itu dalam persekitaran Python yang anda gunakan, kemudian jalankan semula penyelesai. PEP 615 – Sokongan untuk Pangkalan Data Zon Waktu IANA dalam Pustaka Standard
Simpan tarikh asal, nama zon, pilihan waktu berulang dan cap masa UTC yang ditentukan bersama-sama dalam nota kerja anda. Jika pengiraan berbeza antara komputer, bandingkan sumber data zon waktu masing-masing. Memasang pakej sandaran tidak secara automatik menggantikan data sistem yang sudah ditemui oleh Python. Sumber data zoneinfo
Nilai manakah yang perlu anda salin ke alat lain?
Apabila destinasi menerima cap masa UTC, salin nilai Detik UTC, termasuk Z-nya. Sahkan format input yang didokumenkan oleh destinasi sebelum memasukkannya. Medan tarikh biasa tidak dapat mengekalkan semua maklumat yang diwakili oleh cap masa yang telah ditentukan itu; simpan tarikh asal dan zon bernama bersamanya apabila anda perlu mengekalkan tujuan penjadualan.
RFC 9557 mentakrifkan format cap masa lanjutan yang boleh menyertakan akhiran zon bernama, tetapi format itu masih mewakili detik yang telah ditentukan. RFC itu juga mengakui bahawa kemas kini data zon boleh mewujudkan ketidakselarasan antara ofset tersimpan dengan maklumat zon. Gunakan perwakilan lanjutan hanya apabila alat penerima mendokumenkan sokongannya. RFC 9557, skop dan ofset yang tidak konsisten
Akhiri dengan menyemak bahawa output tempatan menunjukkan tarikh yang dimaksudkan pada 00:00:00, zon bernama sepadan dengan input anda, dan sebarang pilihan tengah malam berulang dibuat dengan sengaja. Setelah semakan itu lulus, output UTC ialah detik tengah malam yang ditentukan mengikut peraturan yang digunakan dalam pengiraan tersebut.
Sumber
- Buka atau keluar daripada Terminal pada Mac — Apple
- Menggunakan Python pada macOS — Python Software Foundation
- datetime — Jenis asas tarikh dan waktu — Python Software Foundation
- zoneinfo — Sokongan zon waktu IANA — Python Software Foundation
- PEP 495 – Pembezaan Waktu Tempatan — Python Software Foundation
- PEP 615 – Sokongan untuk Pangkalan Data Zon Waktu IANA dalam Pustaka Standard — Python Software Foundation
- RFC 3339: Tarikh dan Waktu di Internet: Cap Masa — RFC Editor
- RFC 9557: Tarikh dan Waktu di Internet: Cap Masa dengan Maklumat Tambahan — RFC Editor