Tanggal & Waktu dengan DateTime
Olah tanggal secara benar: format, selisih, tambah-kurang, dan zona waktu.
Kenapa Tidak Asal String Saja?
Tanggal terlihat seperti string ("08-10-2026"), tapi string tidak bisa dihitung: "berapa hari dari 28 Feb ke 3 Mar?" butuh kalender, kabisat, dan zona waktu. Class DateTime membungkus kerumitan itu: tanggal menjadi objek yang bisa ditambah, dikurang, dibandingkan, dan diformat dengan benar.
<?php
// Contoh 1: membuat, memformat, dan aritmetika tanggal
$sekarang = new DateTime(); // waktu saat ini
echo $sekarang->format("d M Y H:i"); // "08 Oct 2026 10:30"
$deadline = new DateTime("2026-10-26"); // dari string
$deadline->modify("+7 days"); // tambah 7 hari
echo $deadline->format("d M Y"); // "02 Nov 2026"
$lebaran = new DateTime("2027-03-10");
$selisih = $sekarang->diff($lebaran); // selisih sebagai objek
echo "Sisa " . $selisih->days . " hari"; // total hari
echo $selisih->format("%m bulan %d hari"); // "5 bulan 2 hari"modify() memahami bahasa manusia: "+7 days", "-2 weeks", "+1 month", "next Monday". diff() mengembalikan objek DateInterval dengan properti days, m, d, h yang akurat termasuk tahun kabisat.
<?php
// Contoh 2: zona waktu dan format Indonesia
// Simpan selalu dalam UTC, tampilkan dalam WIB
$utc = new DateTime("now", new DateTimeZone("UTC"));
$wib = clone $utc;
$wib->setTimezone(new DateTimeZone("Asia/Jakarta"));
echo $wib->format("d-m-Y H:i") . " WIB";
// Nama bulan Indonesia (date() hanya Inggris)
$bulanId = ["", "Januari", "Februari", "Maret", "April", "Mei", "Juni",
"Juli", "Agustus", "September", "Oktober", "November", "Desember"];
$tgl = new DateTime("2026-10-08");
echo $tgl->format("d") . " " . $bulanId[(int) $tgl->format("n")]
. " " . $tgl->format("Y"); // "08 Oktober 2026"Aturan emas aplikasi nyata: simpan dalam UTC di database, konversi ke zona user saat tampil. Mencampur zona waktu dalam penyimpanan adalah sumber bug "jadwalku mundur 7 jam" yang legendaris.
Jebakan yang Sering Terjadi
modify() mengubah objek asli. $a = new DateTime(); $b = $a->modify("+1 day"); membuat $a JUGA berubah (sama objek!). Untuk salinan independen, pakai clone atau DateTimeImmutable yang selalu mengembalikan objek baru.
Bulan "n" vs "m". Format "n" = bulan tanpa nol depan (10), "m" = dengan nol (10 tetap, tapi Januari = "01"). Untuk array $bulanId di atas, pakai (int) $tgl->format("n") agar Januari menjadi indeks 1, bukan "01".
Menghitung Umur dan Deadline
Dua perhitungan tanggal paling sering diminta:
<?php
// Umur dari tanggal lahir
$lahir = new DateTime("2008-05-21");
$umur = $lahir->diff(new DateTime())->y;
echo "Umur: $umur tahun\n";
// Deadline: apakah sudah lewat? berapa hari lagi?
$deadline = new DateTime("2026-10-26 23:59:59");
$sekarang = new DateTime();
if ($sekarang > $deadline) {
echo "Sudah lewat!";
} else {
$sisa = $sekarang->diff($deadline);
echo "Sisa {$sisa->days} hari, {$sisa->h} jam";
}
// Objek DateTime bisa dibandingkan langsung dengan < > ==
// karena PHP membandingkan timestamp di dalamnyaPerbandingan langsung ($a > $b) bekerja karena DateTime membandingkan momen waktunya, bukan string formatnya. Jauh lebih aman daripada membandingkan string tanggal manual.
Catatan teknis:
DateTimeImmutableadalah versi yang tidak bisa diubah (setiap operasi mengembalikan objek baru), lebih aman dari bug "berubah diam-diam". Di kode modern, biasakannew DateTimeImmutable()kecuali butuh mutasi.
Tantangan
Hitung mundur acara
Buat script yang menghitung sisa hari dari hari ini sampai "2026-12-25" memakai DateTime::diff, lalu tampilkan "Sisa X hari menuju Natal!".