Aplikasi kita hampir selalu mencatat momen: tanggal pemesanan tiket, jam kedatangan kurir, hingga batas waktu pembayaran tagihan. Data tersebut sering tiba sebagai teks mentah semacam 2026-01-15 08:00:00, dan mengolahnya dengan operasi string seperti explode() atau substr() cepat menjadi rapuh — satu format berbeda merusak seluruh perhitungan. PHP menyediakan jalan keluar berorientasi objek: kelas DateTime menyimpan tanggal, jam, dan zona waktu dalam satu objek yang dilengkapi metode pembacaan, pengubahan, dan perbandingan. Pada chapter ini kita membangun fondasi seluruh section date/time: membuat objek dari string beku, membaca komponennya dengan format(), mengubah nilainya dengan setTime(), setDate(), dan modify(), lalu membandingkan dua objek waktu. Seluruh contoh memakai tanggal beku tahun 2026 dengan zona Asia/Jakarta agar hasilnya dapat Anda reproduksi persis di komputer mana pun.

Membuat Objek DateTime #

Konstruktor DateTime menerima satu argumen string berisi tanggal dan jam dalam format yang dikenali parser PHP, misalnya 2026-01-15 atau 2026-01-15 08:00:00. Argumen kedua bersifat opsional dan menerima objek DateTimeZone; tanpa argumen tersebut, PHP memakai zona waktu default untuk seluruh proses, yaitu UTC pada lingkungan buku ini. Bentuk tanpa argumen, new DateTime(), juga valid dan menyimpan momen saat ini — contoh pada buku ini sengaja menghindari bentuk tersebut agar hasil setiap eksekusi identik. Pembahasan zona waktu yang tuntas menunggu Chapter Timezone .

php
<?php
$waktu = new DateTime("2026-01-15 08:00:00", new DateTimeZone("Asia/Jakarta"));
$tanggalSaja = new DateTime("2026-01-15", new DateTimeZone("Asia/Jakarta"));

echo $waktu->format("Y-m-d H:i:s T") . "\n";
echo $tanggalSaja->format("Y-m-d H:i:s") . "\n";

Output yang Dihasilkan:

text
2026-01-15 08:00:00 WIB
2026-01-15 00:00:00

Mari kita telaah baris-baris kode di atas:

  1. Baris 2: objek DateTime dibuat dari string lengkap tanggal dan jam 2026-01-15 08:00:00 dengan zona Asia/Jakarta; seluruh komponen tanggal, jam, menit, dan detik tersimpan di dalam satu objek.
  2. Baris 3: objek kedua dibuat dari string tanggal saja; komponen jam yang tidak disebut oleh string otomatis terisi 00:00:00.
  3. Baris 5-6: metode format() membaca isi objek kembali sebagai string. Karakter T pada pola mencetak singkatan zona sehingga baris pertama tercetak 2026-01-15 08:00:00 WIB.

Membaca Komponen Waktu dengan format() #

Metode format() menerima satu argumen berupa pola (pattern) dan mengembalikan string hasil pembacaan objek. Setiap huruf pada pola bertindak sebagai karakter pengganti yang mewakili satu komponen tanggal atau jam, sedangkan karakter non-huruf seperti -, /, dan : dicetak apa adanya. Tabel berikut merangkum karakter yang paling sering kita perlukan sepanjang section ini.

KarakterArtiContoh hasil (15 Januari 2026, pukul 08:00:05)
dTanggal, dua digit15
mBulan, dua digit01
YTahun, empat digit2026
HJam format 24 jam, dua digit08
iMenit, dua digit00
sDetik, dua digit05
lNama hari lengkapThursday
NNomor hari ISO-8601 (Senin=1 … Minggu=7)4
php
<?php
$waktu = new DateTime("2026-01-15 08:00:05", new DateTimeZone("Asia/Jakarta"));

echo $waktu->format("d/m/Y") . "\n";
echo $waktu->format("H:i:s") . "\n";
echo $waktu->format("l, d-m-Y") . "\n";
echo "Hari ke-{$waktu->format('N')} dalam minggu\n";

Output yang Dihasilkan:

text
15/01/2026
08:00:05
Thursday, 15-01-2026
Hari ke-4 dalam minggu

Baris demi baris, kode di atas bekerja sebagai berikut:

  1. Baris 4: pola d/m/Y membaca tanggal, bulan, dan tahun, lalu menyisipkan pemisah / di antara nilainya.
  2. Baris 5: pola H:i:s membaca jam, menit, dan detik. Perhatikan bahwa menit memakai huruf i kecil, bukan m yang sudah dipakai untuk bulan.
  3. Baris 6: pola l, d-m-Y mencetak nama hari lengkap terlebih dahulu — tanggal 15 Januari 2026 jatuh pada hari Kamis.
  4. Baris 7: hasil format('N') diinterpolasi ke dalam string berkutip ganda; nilai 4 menegaskan bahwa Kamis adalah hari keempat menurut sistem ISO-8601 yang menghitung Senin sebagai hari pertama.

Mengubah Komponen dengan setTime, setDate, dan modify #

DateTime menyediakan tiga metode pengubahan paling dasar. Metode setTime($jam, $menit, $detik) mengganti komponen jam tanpa menyentuh tanggal; setDate($tahun, $bulan, $tanggal) mengganti tanggal tanpa menyentuh jam; dan modify($ekspresi) menggeser waktu sesuai ekspresi relatif seperti +1 day maupun -2 hours. Ketiganya mengubah objek yang sama di tempat, jadi mari kita amati nilainya berubah tahap demi tahap.

php
<?php
$waktu = new DateTime("2026-01-15 08:00:00", new DateTimeZone("Asia/Jakarta"));

$waktu->setTime(10, 30);
echo $waktu->format("Y-m-d H:i:s") . "\n";

$waktu->setDate(2026, 3, 20);
echo $waktu->format("Y-m-d H:i:s") . "\n";

$waktu->modify("+1 day");
echo $waktu->format("Y-m-d H:i:s") . "\n";

$waktu->modify("-2 hours");
echo $waktu->format("Y-m-d H:i:s") . "\n";

Output yang Dihasilkan:

text
2026-01-15 10:30:00
2026-03-20 10:30:00
2026-03-21 10:30:00
2026-03-21 08:30:00

Mari kita amati perubahan yang terjadi pada tiap tahap:

  1. Baris 4 (setTime(10, 30)): komponen jam diganti menjadi 10:30:00 sedangkan tanggal 2026-01-15 tetap. Argumen detik boleh dihilangkan dan otomatis bernilai 0.
  2. Baris 7 (setDate(2026, 3, 20)): tanggal berganti menjadi 20 Maret 2026 sedangkan jam 10:30:00 dari langkah sebelumnya tetap terbawa.
  3. Baris 10 (modify("+1 day")): waktu bergeser satu hari ke depan menjadi 2026-03-21 10:30:00.
  4. Baris 13 (modify("-2 hours")): jam bergeser dua jam ke belakang menjadi 08:30:00. Tanda plus memajukan waktu, tanda minus memundurkannya.

Membandingkan Dua Objek Waktu #

Objek DateTime dapat dibandingkan langsung menggunakan operator perbandingan <, >, <=, dan >=. PHP menghitung perbandingan dari momen sebenarnya (instant) yang tersimpan di dalam objek, bukan dari teks jam dindingnya, sehingga dua objek dengan zona berbeda tetap diperlakukan secara adil. Operator == memeriksa kesamaan momen, sedangkan === memeriksa apakah dua variabel menunjuk objek yang sama persis.

php
<?php
$jadwalA  = new DateTime("2026-01-15 08:00:00", new DateTimeZone("Asia/Jakarta"));
$jadwalB  = new DateTime("2026-01-15 09:30:00", new DateTimeZone("Asia/Jakarta"));
$waktuUtc = new DateTime("2026-01-15 01:00:00", new DateTimeZone("UTC"));
$salinanA = new DateTime("2026-01-15 08:00:00", new DateTimeZone("Asia/Jakarta"));

var_dump($jadwalA < $jadwalB);    // 08:00 lebih awal daripada 09:30
var_dump($jadwalA == $waktuUtc);  // momen sama walau zona berbeda
var_dump($jadwalA == $salinanA);  // nilai sama
var_dump($jadwalA === $salinanA); // tetapi objeknya berbeda

Output yang Dihasilkan:

text
bool(true)
bool(true)
bool(true)
bool(false)

Empat pemeriksaan di atas memperlihatkan tiga tingkat perbandingan:

  1. Baris 6: pukul 08:00 memang lebih awal daripada 09:30 pada zona yang sama sehingga hasilnya true.
  2. Baris 7: 08:00 WIB dan 01:00 UTC adalah momen yang sama — hanya dibaca dengan zona berbeda — sehingga operator == mengembalikan true.
  3. Baris 8-9: dua objek bernilai identik dianggap sama oleh ==, tetapi === mengembalikan false karena kedua objek dibuat terpisah dan menempati dua lokasi objek yang berbeda.

Gunakan ==, <, dan > untuk logika jadwal karena ketiganya berbicara tentang nilai waktu. Sisakan === untuk kasus khusus ketika kita benar-benar perlu memastikan dua variabel mengarah ke satu objek identik.

Pratinjau Selisih dengan diff() #

Kebutuhan berikutnya setelah membandingkan adalah mengukur jarak antara dua waktu. Metode diff() menerima satu objek waktu sebagai argumen dan mengembalikan objek DateInterval yang menyimpan selisihnya. Kelas DateInterval akan kita bedah tuntas pada Chapter Date Intervals ; untuk saat ini kita cukup membaca dua bentuk keluarannya.

php
<?php
$checkIn  = new DateTime("2026-01-15 08:00:00", new DateTimeZone("Asia/Jakarta"));
$checkOut = new DateTime("2026-01-20 14:00:00", new DateTimeZone("Asia/Jakarta"));

$durasi = $checkIn->diff($checkOut);

echo "Total hari: " . $durasi->days . "\n";
echo $durasi->format("%d hari %h jam %i menit") . "\n";

Output yang Dihasilkan:

text
Total hari: 5
5 hari 6 jam 0 menit

Skenario di atas mengikuti masa inap hotel: check-in pukul 08:00 tanggal 15 Januari dan check-out pukul 14:00 tanggal 20 Januari. Properti days menyimpan total hari penuh, yaitu 5, sedangkan pola %d %h %i pada format() menguraikan selisih menjadi komponen hari, jam, dan menit sehingga tercetak 5 hari 6 jam 0 menit. Angka 6 jam berasal dari selisih pukul 08:00 dan 14:00, terpisah dari hitungan hari penuhnya.

Ringkasan #

DateTime menyimpan tanggal, jam, dan zona dalam satu objek dengan API lengkap: format() untuk membaca komponen, setTime()/setDate()/modify() untuk mengubah, operator perbandingan untuk mengurutkan momen, dan diff() untuk mengukur jarak. Karakter pola seperti d, m, Y, H, i, s, l, dan N menjadi kosakata baca yang akan terus kita pakai di sepanjang section. Namun objek yang berubah di tempat menyimpan risiko tersendiri begitu mulai dilewatkan antar function — itulah pembuka Chapter berikutnya: DateTimeImmutable.

Referensi #