Data waktu jarang datang sebagai object datetime. Ia datang sebagai teks: “15/06/2025” pada baris file CSV, “2025-06-15T10:30:00” pada respons API, atau “15 Juni 2025” yang diketik pengguna pada form. Chapter ini membahas dua arah transformasinya — formatting (object datetime menjadi teks) dan parsing (teks menjadi object datetime) — memakai pasangan method strftime()/strptime(), standar ISO 8601 lewat fromisoformat(), serta cara menghasilkan teks tanggal bergaya Indonesia.
Formatting dengan strftime #
Method strftime() menerima satu argumen berupa format string yang diisi directive — placeholder yang diawali tanda persen. Berikut directive yang paling sering dipakai, dinilai terhadap tanggal 15 Juni 2025 pukul 10:30:
| Directive | Makna | Contoh hasil |
|---|---|---|
%Y | tahun empat digit | 2025 |
%m | bulan dua digit | 06 |
%d | tanggal dua digit | 15 |
%H | jam, format 24 jam | 10 |
%M | menit dua digit | 30 |
%S | detik dua digit | 00 |
%A | nama hari lengkap | Sunday |
%B | nama bulan lengkap | June |
%I | jam, format 12 jam | 10 |
%p | penanda AM/PM | AM |
from datetime import datetime
rapat = datetime(2025, 6, 15, 10, 30)
print(rapat.strftime("%Y-%m-%d"))
print(rapat.strftime("%d/%m/%Y %H:%M"))
print(rapat.strftime("%A, %d %B %Y, pukul %H:%M"))
print(rapat.strftime("%I:%M %p"))Output yang Dihasilkan:
2025-06-15
15/06/2025 10:30
Sunday, 15 June 2025, pukul 10:30
10:30 AMMari kita telaah apa yang terjadi pada baris-baris kode di atas:
- Baris 5 (
strftime("%Y-%m-%d")): setiap directive diganti dengan nilai komponen milikrapat, sedangkan tanda hubung di antara directive dicetak apa adanya. - Baris 6: directive boleh dicampur teks dan tanda baca lain sesuai kebutuhan, termasuk dipakai lebih dari sekali dalam satu format.
- Baris 7 (
%Adan%B): nama hari dan bulan diambil dari pustaka C dalam bahasa Inggris — perilaku bawaan yang kita atasi pada bagian terakhir chapter ini.
Parsing dengan strptime #
Method strptime() bekerja ke arah sebaliknya: membaca teks beserta formatnya, lalu mengembalikan object datetime. Daftar directive yang dipakai sama persis dengan strftime():
from datetime import datetime
teks = "15/06/2025 10:30"
rapat = datetime.strptime(teks, "%d/%m/%Y %H:%M")
print(rapat)
print(type(rapat).__name__)Output yang Dihasilkan:
2025-06-15 10:30:00
datetimePada baris ke-4, datetime.strptime() — sebuah classmethod — menerima dua argumen: teks mentah dan format yang menjelaskan susunannya. Interpreter Python mencocokkan teks dengan format karakter per karakter: %d menelan “15”, garis miring dicocokkan langsung, %m menelan “06”, dan seterusnya. Komponen yang tidak disebut format diisi nilai bawaan — pada contoh di atas detik menjadi 00.
Pasangan kedua method ini mendukung round-trip: teks hasil strftime() dapat dipulihkan menjadi object bernilai identik:
from datetime import datetime
asli = datetime(2025, 6, 15, 10, 30)
teks = asli.strftime("%A %d %B %Y %H:%M")
kembali = datetime.strptime(teks, "%A %d %B %Y %H:%M")
print(teks)
print(kembali == asli)Output yang Dihasilkan:
Sunday 15 June 2025 10:30
TrueKetika Parsing Gagal #
Format string harus cocok dengan teks secara ketat. Simpan kode berikut sebagai parse_rapat.py, lalu jalankan dengan python3 parse_rapat.py:
from datetime import datetime
teks = "15-06-2025 10:30"
rapat = datetime.strptime(teks, "%d/%m/%Y %H:%M")
print(rapat)Output yang Dihasilkan (dicetak interpreter Python ke stderr):
Traceback (most recent call last):
File "parse_rapat.py", line 4, in <module>
rapat = datetime.strptime(teks, "%d/%m/%Y %H:%M")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".../python3.12/_strptime.py", line 653, in _strptime_datetime
tt, fraction, gmtoff_fraction = _strptime(data_string, format)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".../python3.12/_strptime.py", line 432, in _strptime
raise ValueError("time data %r does not match format %r" %
ValueError: time data '15-06-2025 10:30' does not match format '%d/%m/%Y %H:%M'Teks memakai tanda hubung sebagai pemisah tanggal, sementara format mengharapkan garis miring — interpreter Python menolak menebak dan membangkitkan ValueError. Selain ketidakcocokan format, tanggal mustahil juga ditolak meski formatnya benar:
from datetime import datetime
try:
rapat = datetime.strptime("31/02/2025", "%d/%m/%Y")
except ValueError as galat:
print("Input tidak valid:", galat)Output yang Dihasilkan:
Input tidak valid: day is out of range for monthFormat ISO 8601 dengan fromisoformat #
Untuk teks berformat ISO 8601 — standar 2025-06-15T10:30:00 — classmethod fromisoformat() jauh lebih ringkas karena tidak butuh format string:
from datetime import datetime
a = datetime.fromisoformat("2025-06-15T10:30:00")
b = datetime.fromisoformat("2025-06-15 10:30:00")
c = datetime.fromisoformat("2025-06-15T10:30:00+07:00")
print(a)
print(a == b)
print(c.isoformat())Output yang Dihasilkan:
2025-06-15 10:30:00
True
2025-06-15T10:30:00+07:00Huruf T pada string pertama adalah pemisah standar antara tanggal dan jam versi ISO 8601; sejak Python 3.11, fromisoformat() juga menerima variasi lain seperti spasi sebagai pemisah (string kedua), format tanpa pemisah seperti "20250615T1030", serta akhiran "Z" untuk UTC. Offset +07:00 pada string ketiga otomatis menghasilkan object aware sesuai materi Chapter Timezone-Aware datetime. Teks yang bukan ISO 8601 ditolak dengan pesan yang jelas:
from datetime import datetime
try:
print(datetime.fromisoformat("15/06/2025"))
except ValueError as galat:
print("Gagal parsing:", galat)Output yang Dihasilkan:
Gagal parsing: Invalid isoformat string: '15/06/2025'Format Tanggal Gaya Indonesia Tanpa locale #
Directive %A dan %B selalu menghasilkan bahasa Inggris karena keduanya dibaca dari pustaka C. Solusi tanpa dependensi apa pun adalah memetakan nama hari dan bulan secara manual lewat dictionary:
from datetime import datetime
NAMA_HARI = {
"Monday": "Senin", "Tuesday": "Selasa", "Wednesday": "Rabu",
"Thursday": "Kamis", "Friday": "Jumat", "Saturday": "Sabtu",
"Sunday": "Minggu",
}
NAMA_BULAN = {
1: "Januari", 2: "Februari", 3: "Maret", 4: "April",
5: "Mei", 6: "Juni", 7: "Juli", 8: "Agustus",
9: "September", 10: "Oktober", 11: "November", 12: "Desember",
}
def format_indonesia(dt):
hari = NAMA_HARI[dt.strftime("%A")]
bulan = NAMA_BULAN[dt.month]
return f"{hari}, {dt.day} {bulan} {dt.year}"
print(format_indonesia(datetime(2025, 6, 15, 10, 30)))Output yang Dihasilkan:
Minggu, 15 Juni 2025Mari kita telaah function format_indonesia:
- Baris pertama (
NAMA_HARI[dt.strftime("%A")]): mengambil nama hari Inggris daristrftime(), lalu menerjemahkannya lewat dictionaryNAMA_HARI. - Baris kedua (
NAMA_BULAN[dt.month]): mengambil nama bulan langsung dari atribut numerikmonthmelalui dictionaryNAMA_BULAN. - Baris ketiga: merangkai hasilnya dengan f-string — materi Chapter f-strings — menjadi format Indonesia yang akrab bagi pengguna.
Pendekatan manual ini memberi kendali penuh, tetapi menuntut kita mengelola daftar terjemahan sendiri. Dua alternatif lain — module locale yang bergantung pada sistem operasi dan pustaka babel — kita bandingkan pada Chapter Locale dan Formatting.