Pertahankan nilai publikasi yang hanya berisi tanggal dengan menguraikannya sebagai tanggal kalender dan menjadikan tanggal tersebut sebagai acuan utama. Jika ekspor memerlukan stempel waktu UTC, tambahkan konvensi tengah malam UTC secara eksplisit. Panduan Mac Terminal ini menjelaskan perbedaannya dan menguji proses bolak-balik.

Tentukan makna sebenarnya dari kolom publikasi

Misalkan sebuah daftar publikasi berisi nilai sintetis 2028-06-15. Tugas Anda adalah memvalidasi nilai tersebut dan menyiapkannya untuk ekspor tanpa membuatnya ditampilkan sebagai 14 Juni secara tidak sengaja. Sebelum memilih parser, tentukan apakah kolom tersebut mencatat hari publikasi atau waktu publikasi yang sebenarnya.

Keempat konsep ini memiliki peran yang berbeda:

Konsep Contoh sintetis Makna
Tanggal sipil 2028-06-15 Hari kalender, tanpa waktu atau offset
Instant 2028-06-15T00:00:00+00:00 Suatu waktu tertentu yang dinyatakan dalam UTC
Offset UTC +09:00 Selisih antara pembacaan jam lokal dan UTC
Zona bernama America/Los_Angeles Pengenal yang digunakan untuk memperoleh aturan zona waktu yang berlaku

RFC 3339 mendefinisikan full-date secara terpisah dari date-time; tata bahasa stempel waktunya menambahkan waktu dan offset pada tanggal. Karena itu, tanggal publikasi tanpa komponen lain tidak memiliki informasi yang diperlukan untuk mengidentifikasi suatu instant publikasi. Menentukan tengah malam berarti menambahkan informasi yang tidak ada pada masukan. RFC 3339, bagian 5.6

Zona bernama juga memuat lebih banyak informasi daripada satu offset numerik. Dokumentasi Python tentang zoneinfo menunjukkan bagaimana zona dapat menggunakan offset berbeda selama peralihan waktu musim panas. Untuk label yang hanya berisi tanggal, aturan tersebut tidak perlu ditentukan. Python: Dukungan zona waktu IANA

Gunakan aturan keputusan ini sebelum mengekspor:

  • Kolom berarti “dipublikasikan pada hari ini”: pertahankan nilai hanya berupa tanggal selama penyimpanan dan penayangan.
  • Format penerima memerlukan stempel waktu: pertahankan tanggalnya dan turunkan pembawa tengah malam UTC berdasarkan konvensi yang terdokumentasi.
  • Kolom berarti “dipublikasikan pada saat ini”: peroleh waktu dan offset yang sebenarnya, atau waktu dan zona bernama yang diperlukan untuk menetapkan saat tersebut.

Konvensi pembawa berguna untuk kompatibilitas, tetapi tidak dapat memulihkan waktu publikasi yang tidak diketahui. Nama kolom seperti utc_carrier memperlihatkan keterbatasan itu; menyebutnya published_at akan menyiratkan adanya informasi yang tidak pernah diberikan sumbernya.

Pahami sumber kesalahan tanggal sebelumnya

Pertimbangkan dua kemungkinan alur pemrosesan untuk 2028-06-15. Pada alur pertama, program mengada-adakan tengah malam pada offset tetap +09:00, lalu mengonversi instant tersebut ke UTC. Hasilnya adalah 2028-06-14T15:00:00+00:00: pengurangan sembilan jam melewati batas tanggal.

Pada alur kedua, program sengaja membuat tengah malam UTC: 2028-06-15T00:00:00+00:00. Jika instant yang sama ditampilkan pada offset tetap -07:00, hasilnya 2028-06-14T17:00:00-07:00. Ini adalah ilustrasi perhitungan offset, bukan klaim mengenai offset zona bernama pada tanggal tersebut.

Kedua perhitungan mempertahankan instant masing-masing. Namun, keduanya tidak mempertahankan label kalender asli pada setiap zona penayangan. Python menjelaskan bahwa astimezone() menyesuaikan komponen jam sambil mempertahankan waktu UTC yang direpresentasikan. Python: datetime.astimezone()

Implikasi praktisnya, penguraian dan penayangan harus mengikuti kontrak yang sama. Jika tanggal telah ditempatkan dalam pembawa tengah malam UTC, ambil kembali komponen tanggalnya dalam UTC. Jika Anda ingin label publikasi tetap sama di mana pun seseorang membuka ekspor, tampilkan tanggal sipil yang dipertahankan.

Jangan menganggap semua bahasa pemrograman menyediakan informasi yang sama ketika ada informasi yang hilang. ECMAScript menetapkan bahwa bentuk tanggal tanpa offset ditafsirkan sebagai UTC, sedangkan bentuk tanggal-waktu tanpa offset ditafsirkan sebagai waktu lokal. Karena itu, menambahkan T00:00:00 pada string dapat mengubah penafsirannya dalam JavaScript. ECMAScript: Date.parse

Jalankan pemeriksaan tanggal publikasi lengkap di Mac Terminal

Panduan ini memvalidasi tiga tanggal sintetis, mencetak pratinjau bertab, dan menguji penolakan masukan yang formatnya tidak valid. Panduan ini tidak mengubah daftar publikasi atau membuat berkas ekspor.

Di Finder, buka /Applications/Utilities, lalu klik dua kali Terminal. Apple mendokumentasikan ini sebagai cara yang didukung untuk membuka aplikasi baris perintah. Apple: Membuka atau menutup Terminal di Mac

Jalankan perintah berikut untuk memeriksa interpreter Anda:

python3 --version

Gunakan Python 3.11 atau yang lebih baru untuk panduan ini. Jika python3 tidak tersedia atau melaporkan versi yang lebih lama, ikuti petunjuk instalasi resmi untuk macOS sebelum melanjutkan, lalu buka kembali Terminal dan periksa lagi. Python mendokumentasikan installer macOS serta cara menjalankan skrip dengan python3. Python: Menggunakan Python di macOS

Tempel seluruh blok di bawah ini, termasuk PY terakhir, lalu tekan Return. Argumen - memberi tahu Python untuk membaca programnya dari masukan standar. Semua data contoh dan impor sudah disertakan. Python: Baris perintah dan lingkungan

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

Keluaran yang diharapkan:

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 perhitungan offset tetap telah berhasil dijalankan dengan interpreter Python yang tersedia. Petunjuk khusus Mac untuk membuka aplikasi dan memeriksa interpreter mengikuti dokumentasi resmi yang ditautkan.

Mengapa contoh ini mempertahankan hari publikasi

Parser memeriksa dua hal secara terpisah: bentuk string yang tepat dan validitas kalender. Ekspresi regulernya mensyaratkan empat digit tahun, dua digit bulan, dan dua digit hari. Parser tanggal berikutnya menolak tanggal yang tidak mungkin. Ini mencegah kolom publikasi diam-diam menerima stempel waktu, spasi di sekeliling nilai, atau masukan singkat.

Pemeriksaan bentuk yang eksplisit ini penting karena date.fromisoformat() juga menerima representasi ISO lain, termasuk tanggal ringkas dan tanggal minggu. datetime.combine() kemudian menambahkan tengah malam dan UTC secara sengaja. Python: Tipe tanggal dan waktu dasar

Program mengurai seluruh daftar contoh sebelum mencetak tajuk. Jika Anda mengganti salah satu contoh dengan nilai yang tidak valid, eksekusi berhenti sebelum baris pratinjau apa pun muncul. Pemeriksaan masukan tidak valid yang disengaja di bagian akhir adalah pengujian terpisah; pengecualian yang diharapkan ditangkap agar semua kasus penolakan dapat diperiksa.

Dua pernyataan pemeriksaan bolak-balik menyatakan kontraknya. Yang pertama memastikan bahwa penguraian dan pemformatan tanggal menghasilkan kembali label asli. Yang kedua memastikan bahwa pembawa turunan menghasilkan tanggal yang sama saat ditafsirkan dalam UTC. Keduanya memeriksa tugas preservasi yang tepat, bukan sekadar memastikan bahwa suatu stempel waktu dapat dibuat.

Keluaran secara eksplisit menggunakan +00:00. RFC 3339 juga mengizinkan Z sebagai penanda offset UTC, tetapi menambahkan salah satu akhiran itu pada tanggal polos tidak menyediakan komponen waktu yang hilang. Pertahankan bentuk yang hanya berisi tanggal atau buat stempel waktu lengkap dengan sengaja. RFC 3339, bagian 5.6

Diagnosis ekspor yang masih mengubah tanggal

Jika pratinjau hilir menampilkan hari sebelumnya, periksa nilai pada setiap batas pemrosesan. Gunakan contoh tengah sintetis, 2028-06-15, agar Anda dapat membandingkan setiap tahap dengan satu label yang diketahui.

Titik pemeriksaan Yang diharapkan menurut konvensi pembawa Arti jika berbeda
Kolom publikasi asli 2028-06-15 Masukan berubah sebelum diurai
Tanggal hasil penguraian yang ditampilkan sebagai teks 2028-06-15 Penguraian atau normalisasi mengubah label
Pembawa UTC turunan 2028-06-15T00:00:00+00:00 Waktu atau offset lain dimasukkan
Tanggal yang diambil kembali dalam UTC 2028-06-15 Konversi atau ekstraksi menggunakan kontrak yang keliru
Label publikasi yang ditampilkan kepada pembaca 2028-06-15 Penampil mungkin menampilkan pembawa dalam zona lain

Periksa perender secara terpisah dari parser. Pembawa UTC yang benar tetap dapat menghasilkan hari kalender berbeda saat ditampilkan menggunakan pengaturan zona lokal. Untuk label publikasi, berikan tanggal yang hanya berisi tanggal dan telah dipertahankan kepada perender. Jika perender hanya menerima stempel waktu, gunakan opsi penayangan UTC yang terdokumentasi dan verifikasi hasilnya.

Jika alat penerima hanya mendukung instant dan selalu menampilkannya dalam waktu lokal, konvensi tengah malam UTC tidak dapat menjamin label tanggal yang sama. Pertahankan kolom teks terpisah yang hanya berisi tanggal, gunakan kolom tanggal saja yang didukung, atau pilih perender dengan pemformatan UTC eksplisit. Keterbatasan ini mengikuti perhitungan offset di atas; mengubah parser saja tidak dapat mengatasinya.

Hindari juga memperlakukan stempel waktu yang sudah ada seolah-olah merupakan masukan yang hanya berisi tanggal. Untuk instant yang sebenarnya, mengubah zonanya berarti mengonversinya. Python membedakan operasi tersebut dari mengganti tzinfo, yang menambahkan informasi zona tanpa menyesuaikan komponen jam. Python: Perilaku konversi zona waktu

Untuk daftar publikasi Anda, pertahankan publication_date sebagai nilai kalender yang menjadi acuan. Turunkan pembawa UTC hanya pada antarmuka yang memerlukannya, sertakan konvensinya bersama kolom tersebut, dan verifikasi pengambilan tanggal dalam UTC sebelum memercayai pratinjau. Dengan begitu, Anda memiliki cara yang dapat diulang untuk mempertahankan hari yang diberikan tanpa mengada-adakan waktu publikasi.

Sumber