Membuat Kalender Dinamis dengan PHP - Episode 1

Membuat Kalender Dinamis dengan PHP - Episode 1

Table of contents



Membuat Kalender Dinamis dengan PHP: Logika, Estetika, dan Sedikit Cerita di Baliknya - Pernah nggak, kamu lihat tampilan kalender web yang bisa loncat dari bulan ke bulan dengan tombol navigasi rapi, dan kepikiran, “Gimana sih cara bikinnya?” Nah, di balik tampilan sederhana itu, ada sederet logika dan kode yang mengatur waktu dengan presisi dan ya, di artikel ini kita bakal membongkar salah satu contohnya.

Menariknya, potongan kode berikut bukan sekadar eksperimen asal. Ia lahir dari sebuah proyek nyata tapi akhirnya tak pernah sampai ke tangan pengguna. Kadang begitu, ya: ide bagus tidak selalu berlabuh di tempat yang tepat. Tapi daripada nganggur di folder “unused but cool”, lebih baik kita jadikan pelajaran untuk semua yang ingin belajar cara membuat kalender dinamis berbasis PHP.

Logika di Balik Kalender: Navigasi Bulan & Tahun

Kode ini ditulis dengan tujuan agar kalender bisa menampilkan bulan dan tahun yang bisa diganti secara interaktif, baik lewat tombol navigasi maupun dropdown.



Kuncinya ada di bagian:

$year  = isset($_GET['y']) ? (int)$_GET['y'] : date('Y');
$month = isset($_GET['m']) ? (int)$_GET['m'] : date('n');

Logika sederhana ini memastikan bahwa jika pengguna memilih bulan atau tahun tertentu, kalender akan menyesuaikan tampilannya secara otomatis tanpa perlu reload penuh atau repot ubah file manual.

Selain itu, daftar nama bulan diatur dalam array $bulanIndo, agar tampilannya lokal dan mudah dipahami pengguna Indonesia. Navigasi antar bulan juga diatur secara logis dengan:

if ($prevMonth < 1) { $prevMonth = 12; $prevYear--; }
if ($nextMonth > 12) { $nextMonth = 1; $nextYear++; }

Artinya, dari Desember otomatis lompat ke Januari tahun berikutnya, dan sebaliknya.

Detail Tampilan: Antara Estetika dan Fungsionalitas

Desain visualnya sengaja dibuat bersih dan fokus pakai font “Segoe UI”, warna lembut, dan grid rapi agar tanggal mudah dibaca. Warna merah digunakan untuk Minggu dan hari libur, sementara hari ini (today) punya highlight biru lembut agar langsung terbaca.

Ada juga bagian kecil tapi penting: daftar libur nasional. Kode berikut menunjukkan bagaimana kita bisa menandai tanggal-tanggal penting dalam sebulan:

$holidays = [
  '2025-01-01' => 'Tahun Baru 2025 Masehi',
  '2025-01-27' => "Isra' Mi'raj Nabi Muhammad SAW",
  ...
];

Nantinya, daftar ini bisa dikembangkan agar lebih dinamis dan di situlah rencana seri kedua artikel ini muncul: integrasi langsung dengan API Hari Libur Nasional, biar kalender bisa auto-update tanpa perlu sentuhan manual tiap tahun.

Baca juga: Membuat Konversi Mata Uang Otomatis dengan PHP

Rencana Selanjutnya: Integrasi dengan API Hari Libur

Di seri berikutnya, kita bakal melangkah lebih jauh. Kalender ini akan terhubung ke API publik untuk menampilkan hari libur resmi secara otomatis, lengkap dengan deskripsi dan penanda visual. Jadi, bukan cuma kalender statis, tapi jadi alat informatif yang bisa langsung kamu pasang di website perusahaan, sekolah, atau portal komunitas.

Kalender Masehi Indonesia PHP HTML

Penutup: Dari Kode yang Tak Terpakai, Jadi Inspirasi Baru

Kadang kode yang tidak dipakai bukan berarti gagal hanya belum menemukan tempatnya. Kalender kecil ini salah satunya. Dari proyek yang “tak jadi”, kini bisa jadi contoh nyata bagaimana sepotong logika sederhana bisa dikembangkan jadi fitur profesional.

Kode Lengkapnya:

<?php
// Ambil bulan & tahun
$year  = isset($_GET['y']) ? (int)$_GET['y'] : date('Y');
$month = isset($_GET['m']) ? (int)$_GET['m'] : date('n');

// Nama bulan Indonesia
$bulanIndo = [
  1=>"Januari",2=>"Februari",3=>"Maret",4=>"April",5=>"Mei",6=>"Juni",
  7=>"Juli",8=>"Agustus",9=>"September",10=>"Oktober",11=>"November",12=>"Desember"
];

// Navigasi bulan sebelumnya & sesudahnya
$prevMonth = $month - 1;
$prevYear = $year;
$nextMonth = $month + 1;
$nextYear = $year;
if ($prevMonth < 1) { $prevMonth = 12; $prevYear--; }
if ($nextMonth > 12) { $nextMonth = 1; $nextYear++; }

// Hitung jumlah hari dan hari pertama
$daysInMonth = cal_days_in_month(CAL_GREGORIAN, $month, $year);
$firstDay = date('w', strtotime("$year-$month-1"));

// Daftar libur nasional (contoh Januari 2025)
$holidays = [
  '2025-01-01' => 'Tahun Baru 2025 Masehi',
  '2025-01-27' => "Isra' Mi'raj Nabi Muhammad SAW",
  '2025-01-28' => "Cuti Bersama Tahun Baru Imlek 2576 Kongzili",
  '2025-01-29' => "Tahun Baru Imlek 2576 Kongzili"
];
?>
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<title>Kalender <?= $bulanIndo[$month].' '.$year ?></title>
<style>
body{
  font-family: "Segoe UI", Arial, sans-serif;
  background:#fff;
  color:#000;
  text-align:center;
  padding:24px;
}
.header{
  display:flex;
  justify-content:center;
  align-items:center;
  gap:12px;
  margin-bottom:14px;
  flex-wrap:wrap;
}
h2{
  text-transform:capitalize;
  color:#1a4cff;
  margin:0;
  font-size:22px;
}
h2 span{ color:#000; }

.nav-btn{
  background:#f2f2f2;
  border:none;
  border-radius:6px;
  padding:6px 12px;
  font-size:15px;
  cursor:pointer;
  transition:0.2s;
}
.nav-btn:hover{
  background:#e0e0e0;
}

select{
  padding:5px 8px;
  font-size:15px;
  border-radius:6px;
  border:1px solid #ccc;
}

table.kalender{
  width:100%;
  border-collapse:collapse;
  margin:auto;
  max-width:700px;
}
.kalender th{
  text-transform:lowercase;
  padding:8px;
  font-weight:600;
  font-size:15px;
}
.kalender td{
  width:14.28%;
  height:48px;
  text-align:center;
  vertical-align:middle;
  font-size:16px;
  border:0;
}
.minggu{ color:#e50000; }
.sabtu{ color:#444; }
.today{
  background:#eaf3ff;
  border-radius:6px;
  font-weight:bold;
}
.holiday{
  color:#e50000;
  font-weight:bold;
}

.list-libur{
  margin:20px auto 0;
  border-top:1px solid #ddd;
  max-width:700px;
  text-align:left;
  padding-top:10px;
  font-size:15px;
  line-height:1.6;
}
.list-libur span{
  color:#e50000;
  font-weight:bold;
  display:inline-block;
  width:22px;
  text-align:right;
}
</style>
</head>
<body>

<div class="header">
  <form method="get" style="display:flex; align-items:center; gap:8px;">
    <button class="nav-btn" type="submit" name="y" value="<?= $prevYear ?>" formaction="?y=<?= $prevYear ?>&m=<?= $prevMonth ?>">«</button>
    <h2><?= strtolower($bulanIndo[$month]) ?> <span><?= $year ?></span></h2>
    <button class="nav-btn" type="submit" name="y" value="<?= $nextYear ?>" formaction="?y=<?= $nextYear ?>&m=<?= $nextMonth ?>">»</button>

    <select name="m" onchange="this.form.submit()">
      <?php foreach ($bulanIndo as $i=>$b): ?>
        <option value="<?= $i ?>" <?= $i==$month?'selected':'' ?>><?= $b ?></option>
      <?php endforeach; ?>
    </select>

    <select name="y" onchange="this.form.submit()">
      <?php for($yy=date('Y')-5; $yy<=date('Y')+5; $yy++): ?>
        <option value="<?= $yy ?>" <?= $yy==$year?'selected':'' ?>><?= $yy ?></option>
      <?php endfor; ?>
    </select>
  </form>
</div>

<table class="kalender">
  <tr>
    <th class="minggu">minggu</th>
    <th>senin</th>
    <th>selasa</th>
    <th>rabu</th>
    <th>kamis</th>
    <th>jumat</th>
    <th class="sabtu">sabtu</th>
  </tr>
  <tr>
<?php
$day = 1;
$cell = 0;

// Kosong sebelum tanggal 1
for ($i = 0; $i < $firstDay; $i++) {
    echo "<td></td>";
    $cell++;
}

// Cetak tanggal
while ($day <= $daysInMonth) {
    $dateStr = sprintf('%04d-%02d-%02d', $year, $month, $day);
    $isToday = ($dateStr == date('Y-m-d'));
    $classes = [];

    // Minggu
    if ($cell % 7 == 0) $classes[] = 'minggu';
    // Sabtu
    if ($cell % 7 == 6) $classes[] = 'sabtu';
    // Hari ini
    if ($isToday) $classes[] = 'today';
    // Hari libur
    if (isset($holidays[$dateStr])) $classes[] = 'holiday';

    $classAttr = $classes ? ' class="'.implode(' ', $classes).'"' : '';

    echo "<td$classAttr>$day</td>";

    $day++;
    $cell++;

    if ($cell % 7 == 0 && $day <= $daysInMonth) echo "</tr><tr>";
}

// Kosong setelah akhir bulan
while ($cell % 7 != 0) {
    echo "<td></td>";
    $cell++;
}
?>
  </tr>
</table>

<div class="list-libur">
<?php foreach ($holidays as $tgl => $ket): 
  $parts = explode('-', $tgl);
  if ($parts[0] == $year && (int)$parts[1] == $month): ?>
  <div><span><?= (int)$parts[2] ?></span> <?= htmlspecialchars($ket) ?></div>
<?php endif; endforeach; ?>
</div>

</body>
</html>

Kalau kamu juga punya ide digital yang ingin diwujudkan mulai dari website perusahaan, sistem booking, hingga portal edukasi — aku siap bantu mewujudkannya dari konsep sampai live online. Kunjungi Jasa Pembuatan Website Profesional dan biarkan idemu punya rumah digital yang pantas.

[DEMO]



Artikel Terkait