Kekalkan nilai penerbitan tarikh sahaja dengan menghuraikannya sebagai tarikh kalendar dan menjadikan tarikh itu sebagai rujukan utama. Jika eksport memerlukan cap masa UTC, tambahkan konvensyen tengah malam UTC yang jelas. Panduan Terminal Mac ini menunjukkan perbezaannya dan menguji perjalanan pergi balik.

Tentukan maksud sebenar medan penerbitan

Andaikan senarai penerbitan mengandungi nilai sintetik 2028-06-15. Tugas anda adalah untuk mengesahkan nilai itu dan menyediakannya untuk dieksport tanpa memaparkan 14 Jun secara tidak sengaja. Sebelum memilih penghurai, tentukan sama ada medan itu merekodkan hari penerbitan atau saat penerbitan yang sebenar.

Empat konsep ini mempunyai peranan yang berbeza:

Konsep Contoh sintetik Maksud
Tarikh sivil 2028-06-15 Hari kalendar tanpa masa atau ofset
Saat 2028-06-15T00:00:00+00:00 Saat tertentu yang dinyatakan dalam UTC
Ofset UTC +09:00 Perbezaan antara bacaan jam tempatan dengan UTC
Zon bernama America/Los_Angeles Pengecam yang digunakan untuk mendapatkan peraturan zon waktu yang berkenaan

RFC 3339 mentakrifkan full-date secara berasingan daripada date-time; tatabahasa cap masanya menambahkan masa dan ofset pada tarikh. Oleh itu, tarikh penerbitan tanpa maklumat lain tidak mempunyai maklumat yang diperlukan untuk mengenal pasti saat penerbitan. Memilih tengah malam menambahkan maklumat yang tiada dalam input. RFC 3339, seksyen 5.6

Zon bernama juga membawa lebih banyak maklumat daripada satu ofset berangka. Dokumentasi zoneinfo Python menunjukkan cara zon boleh menggunakan ofset yang berbeza semasa peralihan waktu penjimatan siang. Bagi label tarikh sahaja, anda tidak perlu menyelesaikan peraturan tersebut. Python: Sokongan zon waktu IANA

Gunakan peraturan keputusan ini sebelum mengeksport:

  • Medan ini bermaksud “diterbitkan pada hari ini”: kekalkan nilai tarikh sahaja sepanjang penyimpanan dan paparan.
  • Format penerima memerlukan cap masa: kekalkan tarikh dan terbitkan pembawa tengah malam UTC mengikut konvensyen yang didokumenkan.
  • Medan ini bermaksud “diterbitkan pada saat ini”: dapatkan masa dan ofset sebenar, atau masa dan zon bernama yang diperlukan untuk menetapkan saat tersebut.

Konvensyen pembawa berguna untuk keserasian, tetapi ia tidak mendapatkan semula waktu penerbitan yang tidak diketahui. Nama medan seperti utc_carrier menjadikan batasan itu jelas; memanggilnya published_at akan membayangkan maklumat yang tidak pernah diberikan oleh sumber.

Fahami bagaimana ralat hari sebelumnya berlaku

Pertimbangkan dua laluan pemprosesan yang mungkin bagi 2028-06-15. Dalam laluan pertama, program mereka tengah malam pada ofset tetap +09:00, kemudian menukar saat itu kepada UTC. Hasilnya ialah 2028-06-14T15:00:00+00:00: penolakan sembilan jam melangkaui sempadan tarikh.

Dalam laluan kedua, program sengaja membina tengah malam UTC: 2028-06-15T00:00:00+00:00. Memaparkan saat yang sama pada ofset tetap -07:00 menghasilkan 2028-06-14T17:00:00-07:00. Ini ialah pengiraan ofset untuk tujuan ilustrasi, bukannya dakwaan tentang ofset zon bernama pada tarikh tersebut.

Kedua-dua pengiraan mengekalkan saat masing-masing. Tiada satu pun mengekalkan label kalendar asal dalam setiap zon paparan. Python mendokumenkan bahawa astimezone() melaraskan medan jam sambil mengekalkan masa UTC yang diwakili. Python: datetime.astimezone()

Implikasi praktikalnya ialah penghuraian dan paparan memerlukan kontrak yang sama. Jika tarikh telah dimasukkan ke dalam pembawa tengah malam UTC, dapatkan semula medan kalendarnya dalam UTC. Jika anda mahu label penerbitan kekal sama di mana-mana sahaja seseorang membuka eksport itu, paparkan tarikh sivil yang dikekalkan.

Jangan anggap setiap bahasa membekalkan maklumat yang sama apabila maklumat itu tiada. ECMAScript menetapkan bahawa bentuk tarikh sahaja tanpa ofset ditafsirkan sebagai UTC, manakala bentuk tarikh-masa tanpa ofset ditafsirkan sebagai waktu tempatan. Oleh itu, menambahkan T00:00:00 pada rentetan boleh mengubah tafsirannya dalam JavaScript. ECMAScript: Date.parse

Jalankan semakan tarikh penerbitan lengkap dalam Terminal Mac

Panduan ini mengesahkan tiga tarikh sintetik, mencetak pratonton berpisah tab dan menguji penolakan input yang tidak sah. Panduan ini tidak mengubah senarai penerbitan atau mencipta fail eksport.

Dalam Finder, buka /Applications/Utilities, kemudian klik dua kali Terminal. Apple mendokumenkan cara ini sebagai kaedah yang disokong untuk membuka aplikasi baris perintah. Apple: Buka atau keluar daripada Terminal pada Mac

Jalankan perintah berikut untuk menyemak penterjemah anda:

python3 --version

Gunakan Python 3.11 atau versi lebih baharu untuk panduan ini. Jika python3 tidak tersedia atau melaporkan versi yang lebih lama, ikuti arahan pemasangan rasmi untuk macOS sebelum meneruskan, kemudian buka semula Terminal dan semak sekali lagi. Python mendokumenkan pemasang macOSnya serta cara menjalankan skrip dengan python3. Python: Menggunakan Python pada macOS

Tampal seluruh blok di bawah, termasuk PY yang terakhir, kemudian tekan Return. Argumen - memberitahu Python supaya membaca atur caranya daripada input standard. Semua data sampel dan import disertakan. Python: Baris perintah dan persekitaran

python3 - <<'PY'
import re
from datetime import date, datetime, time, timezone


def parse_publication_date(text):
    if not isinstance(text, str) or re.fullmatch(
        r"[0-9]{4}-[0-9]{2}-[0-9]{2}", text
    ) is None:
        raise ValueError("Expected YYYY-MM-DD")
    return date.fromisoformat(text)


def utc_carrier(day):
    return datetime.combine(day, time(0), tzinfo=timezone.utc)


samples = ["2028-02-29", "2028-06-15", "2028-12-31"]
parsed = [(text, parse_publication_date(text)) for text in samples]

print("publication_date\tutc_carrier")
for original, day in parsed:
    carrier = utc_carrier(day)
    assert day.isoformat() == original
    assert carrier.astimezone(timezone.utc).date() == day
    print(day.isoformat(), carrier.isoformat(timespec="seconds"), sep="\t")

for invalid in [
    "2027-02-29",
    "2028-6-15",
    "2028-06-15T00:00:00",
    " 2028-06-15",
]:
    try:
        parse_publication_date(invalid)
    except ValueError:
        pass
    else:
        raise AssertionError(f"Unexpected acceptance: {invalid!r}")

print("Round-trip and rejection checks passed.")
PY

Output yang dijangka ialah:

publication_date	utc_carrier
2028-02-29	2028-02-29T00:00:00+00:00
2028-06-15	2028-06-15T00:00:00+00:00
2028-12-31	2028-12-31T00:00:00+00:00
Round-trip and rejection checks passed.

Contoh dan dua pengiraan ofset tetap telah berjaya dijalankan menggunakan penterjemah Python yang tersedia. Arahan khusus Mac untuk membuka aplikasi dan penterjemah adalah berdasarkan dokumentasi rasmi yang dipautkan.

Mengapa contoh ini mengekalkan hari penerbitan

Penghurai menyemak dua perkara secara berasingan: bentuk rentetan yang tepat dan kesahihan tarikh kalendar. Ungkapan nalar itu memerlukan empat digit tahun, dua digit bulan dan dua digit hari. Penghurai tarikh kemudian menolak tarikh yang mustahil. Ini menghalang lajur penerbitan daripada menerima cap masa, ruang di sekeliling teks atau input yang disingkat secara senyap.

Semakan bentuk yang jelas ini penting kerana date.fromisoformat() turut menerima perwakilan ISO lain, termasuk tarikh padat dan tarikh minggu. datetime.combine() kemudian membekalkan tengah malam dan UTC dengan sengaja. Python: Jenis tarikh dan masa asas

Program menghuraikan keseluruhan senarai sampel sebelum mencetak pengepala. Jika anda menggantikan satu sampel dengan nilai yang tidak sah, pelaksanaan akan berhenti sebelum sebarang baris pratonton dipaparkan. Semakan input tidak sah yang disengajakan pada penghujung ialah ujian berasingan; pengecualian yang dijangka ditangkap supaya semua kes penolakan dapat disemak.

Dua pengesahan perjalanan pergi balik menyatakan kontraknya. Yang pertama mengesahkan bahawa penghuraian dan pemformatan tarikh menghasilkan semula label asal. Yang kedua mengesahkan bahawa pembawa terbitan menghasilkan tarikh yang sama apabila ditafsirkan dalam UTC. Bersama-sama, kedua-duanya menyemak tugas pengekalan yang tepat, bukan sekadar memastikan suatu cap masa boleh dihasilkan.

Output menggunakan +00:00 secara jelas. RFC 3339 juga membenarkan Z sebagai penanda ofset UTC, tetapi menambahkan mana-mana akhiran itu pada tarikh biasa tidak membekalkan komponen masa yang tiada. Kekalkan bentuk tarikh sahaja atau bina cap masa penuh dengan sengaja. RFC 3339, seksyen 5.6

Diagnosis eksport yang masih mengubah tarikh

Jika pratonton seterusnya menunjukkan hari sebelumnya, periksa nilai pada setiap sempadan. Gunakan sampel tengah sintetik, 2028-06-15, supaya anda boleh membandingkan setiap peringkat dengan satu label yang diketahui.

Titik semakan Jangkaan di bawah konvensyen pembawa Petunjuk jika berbeza
Medan penerbitan asal 2028-06-15 Input berubah sebelum dihuraikan
Tarikh terhurai yang dipaparkan sebagai teks 2028-06-15 Penghuraian atau penormalan mengubah label
Pembawa UTC terbitan 2028-06-15T00:00:00+00:00 Masa atau ofset lain telah diperkenalkan
Tarikh yang diperoleh semula dalam UTC 2028-06-15 Penukaran atau pengekstrakan menggunakan kontrak yang salah
Label penerbitan yang dipaparkan kepada pembaca 2028-06-15 Pemapar mungkin memaparkan pembawa dalam zon lain

Semak pemapar secara berasingan daripada penghurai. Pembawa UTC yang betul masih boleh menghasilkan hari kalendar yang berbeza apabila dipaparkan menggunakan tetapan zon tempatan. Untuk label penerbitan, berikan pemapar nilai tarikh sahaja yang dikekalkan. Jika pemapar hanya menerima cap masa, gunakan pilihan paparan UTC yang didokumenkan dan sahkan hasilnya.

Jika alat penerima hanya menyokong saat dan sentiasa memaparkannya secara tempatan, konvensyen tengah malam UTC tidak dapat menjamin label tarikh yang tidak berubah. Kekalkan lajur teks tarikh sahaja yang berasingan, gunakan medan tarikh sahaja yang disokong atau pilih pemapar dengan pemformatan UTC yang jelas. Batasan ini berpunca daripada pengiraan ofset di atas; menukar penghurai sahaja tidak dapat mengatasinya.

Elakkan juga daripada menganggap cap masa sedia ada sebagai input tarikh sahaja. Bagi saat sebenar, menukar zonnya bermaksud menukarkannya. Python membezakan operasi itu daripada menggantikan tzinfo, yang melampirkan maklumat zon tanpa melaraskan medan jam. Python: Tingkah laku penukaran zon waktu

Bagi senarai penerbitan anda, kekalkan publication_date sebagai nilai kalendar yang berautoriti. Terbitkan pembawa UTC hanya pada antara muka yang memerlukannya, sertakan konvensyen tersebut bersama medan berkenaan dan sahkan pengekstrakan UTC sebelum mempercayai pratonton. Dengan itu, anda mempunyai cara yang boleh diulang untuk mengekalkan hari yang diberikan tanpa mereka-reka saat penerbitan.

Sumber