Tanggal & Waktu (Date/Time)

Mengelola tanggal dan waktu adalah kebutuhan umum di hampir semua aplikasi web — mulai dari menampilkan "2 jam yang lalu", format tanggal Indonesia, hingga menghitung selisih hari antara dua tanggal.

Dasar: Fungsi date() dan time()

<?php
// Waktu saat ini dalam format yang bisa dibaca
echo date('Y-m-d');        // 2026-04-11
echo date('H:i:s');        // 07:30:45
echo date('d F Y');        // 11 April 2026
echo date('l, d M Y');     // Friday, 11 Apr 2026

// Unix Timestamp: jumlah detik sejak 1 Januari 1970
echo time();  // 1776076245 (contoh)

Format Date yang Sering Dipakai

FormatContohKeterangan
Y-m-d2026-04-11ISO 8601 (standar database)
d/m/Y11/04/2026Format Indonesia
d F Y11 April 2026Bulan lengkap
H:i:s14:30:00Waktu 24 jam
h:i A02:30 PMWaktu 12 jam
D, d MFri, 11 AprHari singkat
lFridayNama hari lengkap
U1776076245Unix timestamp

Timezone (Zona Waktu)

Indonesia punya 3 zona waktu. Selalu set timezone di awal aplikasi:

<?php
// Set timezone Indonesia (WIB = Western Indonesian Time)
date_default_timezone_set('Asia/Jakarta');  // WIB (UTC+7)
// date_default_timezone_set('Asia/Makassar');  // WITA (UTC+8)
// date_default_timezone_set('Asia/Jayapura');  // WIT (UTC+9)

echo date('Y-m-d H:i:s');  // Sekarang dalam WIB
WARNING
// Simpan ke database: UTC
$utc = gmdate('Y-m-d H:i:s');

// Tampilkan ke user: WIB
date_default_timezone_set('Asia/Jakarta');
echo date('d M Y H:i', strtotime($utc . ' UTC'));

strtotime() — Parse Teks ke Timestamp

Fungsi sihir PHP yang bisa mengubah bahasa manusia menjadi timestamp:

<?php
// Dari format tanggal
echo date('Y-m-d', strtotime('2026-04-11'));  // 2026-04-11

// Relatif ke sekarang
echo date('Y-m-d', strtotime('tomorrow'));        // 2026-04-12
echo date('Y-m-d', strtotime('next monday'));     // 2026-04-13
echo date('Y-m-d', strtotime('+7 days'));         // 2026-04-18
echo date('Y-m-d', strtotime('+1 month'));        // 2026-05-11
echo date('Y-m-d', strtotime('-3 days'));         // 2026-04-08
echo date('Y-m-d', strtotime('first day of next month'));  // 2026-05-01
echo date('Y-m-d', strtotime('last day of this month'));   // 2026-04-30

DateTime Object (Cara Modern)

Untuk operasi yang lebih kompleks, gunakan class DateTime:

<?php
// Buat objek DateTime
$sekarang = new DateTime();  // Waktu saat ini
$tanggal  = new DateTime('2026-04-11');  // Tanggal spesifik
$custom   = new DateTime('2026-12-25 08:00:00');

// Format output
echo $sekarang->format('Y-m-d H:i:s');  // 2026-04-11 07:30:00
echo $sekarang->format('d F Y');         // 11 April 2026

// Modifikasi tanggal
$sekarang->modify('+7 days');
echo $sekarang->format('Y-m-d');  // 2026-04-18

$sekarang->modify('-1 month');
echo $sekarang->format('Y-m-d');  // 2026-03-18

DateTime vs DateTimeImmutable

<?php
// ⚠️ DateTime: MUTABLE — modify() mengubah objek asli
$tanggal = new DateTime('2026-04-11');
$besok = $tanggal->modify('+1 day');
echo $tanggal->format('Y-m-d');  // 2026-04-12 ← Objek asli BERUBAH!
echo $besok->format('Y-m-d');    // 2026-04-12 ← Sama!

// ✅ DateTimeImmutable: IMMUTABLE — modify() membuat objek BARU
$tanggal = new DateTimeImmutable('2026-04-11');
$besok = $tanggal->modify('+1 day');
echo $tanggal->format('Y-m-d');  // 2026-04-11 ← Objek asli TETAP!
echo $besok->format('Y-m-d');    // 2026-04-12 ← Objek baru
TIP

Selalu Prefer DateTimeImmutableDateTimeImmutable untuk menghindari bug tak terduga. Objek yang tidak bisa berubah (immutable) lebih mudah di-debug dan lebih aman dipakai di banyak tempat.

Menghitung Selisih Waktu

<?php
$mulai  = new DateTimeImmutable('2026-01-01');
$selesai = new DateTimeImmutable('2026-04-11');

// DateInterval: selisih antara dua tanggal
$selisih = $mulai->diff($selesai);

echo $selisih->days;    // 100 (total hari)
echo $selisih->m;       // 3 (bulan)
echo $selisih->d;       // 10 (sisa hari)

// Format selisih
echo $selisih->format('%m bulan dan %d hari');  // 3 bulan dan 10 hari

Contoh: "Waktu yang Lalu"

<?php
function waktuYangLalu(string $tanggal): string {
    $waktu = new DateTimeImmutable($tanggal);
    $sekarang = new DateTimeImmutable();
    $selisih = $sekarang->diff($waktu);

    if ($selisih->y > 0) return $selisih->y . ' tahun yang lalu';
    if ($selisih->m > 0) return $selisih->m . ' bulan yang lalu';
    if ($selisih->d > 0) return $selisih->d . ' hari yang lalu';
    if ($selisih->h > 0) return $selisih->h . ' jam yang lalu';
    if ($selisih->i > 0) return $selisih->i . ' menit yang lalu';
    return 'Baru saja';
}

echo waktuYangLalu('2026-04-10 20:00:00');  // 11 jam yang lalu
echo waktuYangLalu('2026-03-01');            // 1 bulan yang lalu

Format Tanggal Indonesia

<?php
function tanggalIndonesia(string $tanggal): string {
    $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'
    ];

    $hari = [
        'Sunday' => 'Minggu', 'Monday' => 'Senin', 'Tuesday' => 'Selasa',
        'Wednesday' => 'Rabu', 'Thursday' => 'Kamis', 'Friday' => 'Jumat',
        'Saturday' => 'Sabtu'
    ];

    $dt = new DateTimeImmutable($tanggal);
    $namaHari  = $hari[$dt->format('l')];
    $namaBulan = $bulan[(int)$dt->format('m')];
    $tgl = $dt->format('d');
    $tahun = $dt->format('Y');

    return "$namaHari, $tgl $namaBulan $tahun";
}

echo tanggalIndonesia('2026-04-11');  // Jumat, 11 April 2026

Validasi Tanggal

<?php
// checkdate(bulan, hari, tahun) — cek apakah tanggal valid
var_dump(checkdate(2, 29, 2024));  // true (2024 = tahun kabisat)
var_dump(checkdate(2, 30, 2024));  // false (30 Februari tidak ada!)
var_dump(checkdate(13, 1, 2026));  // false (bulan 13 tidak ada)

// Validasi format dari input user
function validasiTanggal(string $input): bool {
    $dt = DateTime::createFromFormat('Y-m-d', $input);
    return $dt !== false && $dt->format('Y-m-d') === $input;
}

var_dump(validasiTanggal('2026-04-11'));  // true
var_dump(validasiTanggal('2026-02-30'));  // false
var_dump(validasiTanggal('bukan-tanggal')); // false

Contoh di Aplikasi: Filter Data per Periode

<?php
// Filter pesanan 30 hari terakhir
$tigaPuluhHariLalu = (new DateTimeImmutable())
    ->modify('-30 days')
    ->format('Y-m-d');

$stmt = $pdo->prepare("
    SELECT * FROM pesanan 
    WHERE tanggal_pesan >= ? 
    ORDER BY tanggal_pesan DESC
");
$stmt->execute([$tigaPuluhHariLalu]);
$pesanan = $stmt->fetchAll();

Latihan

  1. Buat fungsi umurDariTanggalLahir(string $tanggalLahir): int — hitung umur dari tanggal lahir
  2. Buat fungsi yang menampilkan "Selamat Pagi / Siang / Sore / Malam" berdasarkan jam saat ini
  3. Tampilkan daftar pesanan dengan kolom "Tanggal" dalam format Indonesia dan kolom "Waktu Lalu"

Selanjutnya

Kamu sudah bisa mengelola tanggal dan waktu dengan benar! Lanjut ke Keamanan Password → untuk belajar cara mengamankan password user.