TL;DR
Pandas to_datetime ngubah kolom yang isinya teks atau angka jadi tipe datetime asli, biar bisa disortir, dihitung selisihnya, dan diekstrak bulan atau tahunnya. Buat tanggal format Indonesia (hari/bulan/tahun), pakai argumen dayfirst=True atau format eksplisit. Data tanggal berantakan bisa diamankan pakai errors='coerce' yang ngubah nilai gagal jadi NaT, bukan bikin seluruh proses error.
Pandas to_datetime ngubah kolom yang isinya teks atau angka jadi tipe datetime asli, biar bisa disortir, dihitung selisihnya, dan diekstrak bulan atau tahunnya. Satu fungsi buat beresin kolom tanggal yang kebaca sebagai teks.
Ini masalah yang hampir tiap analis kena. Kamu baca file penjualan, kolom tanggalnya kelihatan normal, tapi begitu mau disortir kronologis, urutannya kacau. Penyebabnya, pandas nganggap kolom itu teks biasa, bukan tanggal.
Selama tipenya masih teks, "31 Januari" bakal dianggap lebih kecil dari "5 Februari" karena diurutkan seperti abjad. to_datetime yang benerin ini.
pd.to_datetime adalah fungsi pandas yang ngubah data jadi tipe datetime64. Input bisa berupa kolom teks, angka unix timestamp, atau list tanggal. Outputnya objek tanggal yang ngerti urutan waktu, jadi bisa dibandingkan, dikurangi, dan dipecah jadi komponen tahun, bulan, hari.
Bedanya sama teks biasa penting banget. Tanggal asli bisa dikurangi buat dapat selisih hari. Teks nggak bisa. Konsep ini pondasi buat semua analisa time series, dari tren penjualan sampai retensi pelanggan.
import pandas as pd
df['tanggal'] = pd.to_datetime(df['tanggal'])
Buat tanggal format standar internasional (tahun-bulan-hari), satu baris ini udah cukup. Cek hasilnya pakai df.dtypes, kolomnya harus berubah dari object jadi datetime64[ns].
Contoh lengkap dari data mentah:
import pandas as pd
data = {'tanggal': ['2026-01-05', '2026-01-12', '2026-02-03'],
'omzet': [120000, 95000, 210000]}
df = pd.DataFrame(data)
print(df.dtypes) # tanggal: object
df['tanggal'] = pd.to_datetime(df['tanggal'])
print(df.dtypes) # tanggal: datetime64[ns]
Data Indonesia sering ditulis hari/bulan/tahun, misalnya 03/04/2026 buat 3 April. Pandas defaultnya baca bulan dulu (gaya Amerika), jadi bisa salah artiin jadi 4 Maret. Pakai dayfirst=True biar urutannya benar.
df['tanggal'] = pd.to_datetime(df['tanggal'], dayfirst=True)
Cara yang lebih aman dan lebih cepat, tulis formatnya eksplisit. Pandas jadi nggak perlu nebak pola tiap baris.
df['tanggal'] = pd.to_datetime(df['tanggal'], format='%d/%m/%Y')
Kode format yang sering kepakai: %d hari, %m bulan angka, %Y tahun 4 digit, %y tahun 2 digit, %H jam, %M menit. Kalau datamu 05-Jan-2026, formatnya '%d-%b-%Y'.
| Bentuk data | format yang dipakai |
|---|---|
| 05/01/2026 | %d/%m/%Y |
| 2026-01-05 | %Y-%m-%d |
| 05-Jan-2026 | %d-%b-%Y |
| 05/01/2026 14:30 | %d/%m/%Y %H:%M |
Data dunia nyata jarang bersih. Ada typo, ada teks nyasar kayak "belum diisi", ada baris kosong. Kalau to_datetime ketemu nilai yang nggak bisa dia baca, defaultnya dia bikin error dan seluruh proses berhenti.
errors='coerce' ngubah perilaku itu. Nilai yang gagal jadi NaT (Not a Time), semacam nilai kosong buat tanggal, dan baris lain tetap jalan.
df['tanggal'] = pd.to_datetime(df['tanggal'], errors='coerce', dayfirst=True)
# Hitung berapa baris yang gagal
jml_gagal = df['tanggal'].isna().sum()
print(f'Baris tanggal bermasalah: {jml_gagal}')
Ini bagian dari kerja data cleansing. Angka jml_gagal itu ukuran seberapa kotor kolom tanggalmu, dan sering jadi temuan pertama yang perlu dilaporin.
Kalau datamu dari sistem log atau API, tanggalnya sering berupa angka besar: unix timestamp, yaitu jumlah detik sejak 1 Januari 1970. Pakai argumen unit biar pandas ngerti angkanya itu waktu.
# 1767571200 = detik sejak 1970
df['waktu'] = pd.to_datetime(df['unix'], unit='s')
# Kalau angkanya milidetik (13 digit)
df['waktu'] = pd.to_datetime(df['unix'], unit='ms')
Salah pilih unit bikin tanggal meleset jauh. Patokan cepat: 10 digit biasanya detik, 13 digit biasanya milidetik.
Setelah kolom jadi datetime, dt accessor kebuka. Dari sini kamu bisa ambil komponen tanggal buat groupby atau filter.
df['tahun'] = df['tanggal'].dt.year
df['bulan'] = df['tanggal'].dt.month
df['nama_hari'] = df['tanggal'].dt.day_name()
# Ringkasan omzet per bulan
per_bulan = df.groupby(df['tanggal'].dt.to_period('M'))['omzet'].sum()
Accessor ini cuma jalan kalau tipenya udah datetime. Kalau masih object, dt bakal error. Itu alasan konversi harus jadi langkah pertama.
Toko Berkah itu dataset latihan ngulikdata, toko kelontong online dengan 1.240 transaksi selama 6 bulan. Kolom tanggalnya berantakan karena diinput manual dari tiga kasir berbeda. Ada yang nulis 05/01/2026, ada 5-1-2026, ada yang kosong.
Setelah dijalankan pd.to_datetime dengan errors='coerce' dan dayfirst=True, hasilnya kebuka. Dari 1.240 baris, 37 baris (3%) jadi NaT karena formatnya kacau atau kosong. Semua 37 itu ternyata dari satu kasir yang kebiasaan ngetik tanggal pakai spasi.
Setelah tanggal bersih, ekstrak dt.day_name() nunjukin pola yang berguna: Sabtu nyumbang 24% dari total transaksi, hampir dua kali lipat rata-rata hari biasa yang 13%. Temuan ini bikin pemilik toko mindahin jadwal promo mingguan ke Jumat malam, buat narik lonjakan belanja akhir pekan lebih awal.
pd.to_datetime nggak ngubah kolom di tempat. Kamu harus nyimpen balik: df['tanggal'] = pd.to_datetime(df['tanggal']). Lupa bagian kiri, dan datanya nggak berubah sama sekali.
Tanggal 03/04/2026 tanpa dayfirst bakal dibaca 4 Maret, bukan 3 April. Buat data Indonesia, selalu set dayfirst=True atau format eksplisit. Salah ini diam-diam, angkanya tetap valid tapi maknanya keliru.
errors='ignore' bikin nilai gagal dibiarkan apa adanya sebagai teks. Akibatnya kolom tetap bertipe object dan kamu kira udah beres. Pilih 'coerce' biar yang gagal jelas kelihatan sebagai NaT.
Selalu jalankan df.dtypes setelah konversi. Kalau masih object, berarti ada yang gagal senyap. Konsep tanggal ini juga kepakai di SQL, dan polanya mirip. Kamu bisa bandingin sama fungsi tanggal di SQL.
Buat daftar lengkap argumen resmi, cek dokumentasi pandas.to_datetime.
Waktu pandas baca CSV atau Excel, kolom tanggal sering dianggap teks biasa dan diberi tipe object. Ini kejadian kalau formatnya nggak standar, ada campuran format, atau ada nilai kosong. Selama tipenya object, kamu nggak bisa sortir kronologis atau hitung selisih hari. Jalankan pd.to_datetime dulu buat ngubahnya jadi datetime64 yang beneran ngerti tanggal.
Pakai dayfirst=True, misalnya pd.to_datetime(df['tgl'], dayfirst=True). Ini bikin pandas baca 03/04/2026 sebagai 3 April, bukan 4 Maret. Cara yang lebih aman, tulis format eksplisit format='%d/%m/%Y'. Format eksplisit juga lebih cepat di data besar karena pandas nggak perlu nebak pola tiap baris.
errors='coerce' bikin nilai yang gagal dikonversi diubah jadi NaT, semacam nilai kosong buat tanggal, bukan bikin seluruh proses berhenti dengan error. Ini penting buat data dunia nyata yang sering ada typo atau teks nyasar di kolom tanggal. Setelah konversi, kamu bisa hitung berapa baris jadi NaT buat ngukur seberapa kotor datanya.
Pakai argumen unit. Kalau angkanya detik sejak 1970, tulis pd.to_datetime(df['ts'], unit='s'). Kalau milidetik, pakai unit='ms'. Salah pilih unit bikin tanggalnya meleset jauh, misalnya jadi tahun 1970 atau 55000. Cek dulu panjang angkanya: 10 digit biasanya detik, 13 digit biasanya milidetik.
Pakai dt accessor. Setelah kolom jadi datetime, kamu bisa ambil df['tgl'].dt.year, df['tgl'].dt.month, atau df['tgl'].dt.day_name(). Accessor ini cuma jalan kalau tipenya udah datetime, bukan object. Buat agregasi bulanan, ekstrak dt.to_period('M') lalu groupby hasilnya.
Coba sekarang: ambil satu file penjualan yang kolom tanggalnya bandel, jalankan to_datetime dengan errors='coerce', lalu hitung berapa baris jadi NaT. Angka itu titik awal buat bersihin datanya.
Habis rapiin tanggal, langkah lanjutannya biasanya agregasi per periode. Baca cara format tanggal di Excel kalau kamu juga sering pindah data antara Python dan spreadsheet.
Mau praktek langsung? Mulai latihan SQL gratis
Latihan interaktif, langsung di browser.
Nama toko ketik campur huruf besar-kecil, spasi nyasar di ujung, atau kode produk nempel jadi satu. Accessor .str di pandas ngerapiin semua itu tanpa loop.
Model machine learning cuma ngerti angka, bukan teks kayak merah atau biru. get_dummies ngubah kolom kategori jadi kolom 0/1 dalam satu baris kode.
Cara pakai pandas crosstab buat bikin tabel silang yang menghitung frekuensi antar dua kategori. Contoh analisis kategori produk per kota UMKM.