Cara Menghitung ISO 8601 Week Number dengan JavaScript Murni
Pernah dapat task dari bos untuk menampilkan "Minggu ke-berapa tahun ini" di dashboard laporan, lalu berpikir cukup dengan membagi jumlah hari dengan angka tujuh? Eits, dunia penanggalan tidak sesederhana itu, lur!
Membuat fitur kalender atau pelaporan performa mingguan di antarmuka web sering kali menjadi jebakan Batman bagi para Frontend Developer. Secara logika mentah, kita mungkin berpikir bahwa minggu pertama selalu dimulai pada tanggal 1 Januari. Kenyataannya, standar industri logistik, perbankan, dan manufaktur berpegang teguh pada sistem kalender ISO 8601.
Kalau kamu menggunakan library berat seperti Moment.js, hal ini mungkin selesai dengan satu baris pemanggilan fungsi. Tapi hari gini, memasukkan library raksasa hanya untuk mencari angka minggu tentu sangat tidak efisien untuk performa aplikasimu. Untungnya, kita bisa mengeksekusi logika ini dengan Vanilla JavaScript.

Kenapa Tidak Bisa Asal Bagi 7?
Standar internasional ISO 8601 menetapkan aturan yang cukup unik dan strict terkait definisi sebuah minggu. Sebuah minggu (dimulai dari hari Senin) baru bisa diakui sebagai "Minggu ke-1" pada tahun tersebut HANYA JIKA minggu itu memiliki hari Kamis pertama di tahun yang sama.
Artinya, jika tanggal 1 Januari jatuh pada hari Jumat, Sabtu, atau Minggu, maka hari-hari tersebut masih nebeng dan dihitung sebagai minggu terakhir (minggu ke-52 atau 53) dari tahun sebelumnya. Ribet? Memang. Tapi dengan menyusun algoritma penggeseran hari yang tepat di JavaScript, kalkulasi ini bisa dilakukan dengan instan.
Script JavaScript Murni ISO Week Number
Di bawah ini adalah kode JavaScript siap pakai yang tidak hanya menghitung minggu saat ini (current week), tetapi juga sudah saya lengkapi dengan contoh integrasi DOM untuk menampilkan output dari interaksi kotak input tanggal. Silakan salin snippet ini ke proyekmu.
<script>
/**
* Fungsi buat ngitung ISO 8601 Week Number
* Nggak bisa cuma dibagi 7, karena standar ISO netapin minggu ke-1
* adalah minggu yang punya hari Kamis pertama di tahun tersebut.
*/
function getWeekNumber(d) {
// Copy tanggal biar nggak ngubah referensi asli
const date = new Date(d.getTime());
// Set jam ke 00:00:00 biar aman dari offset zona waktu
date.setHours(0, 0, 0, 0);
// Geser ke hari Kamis di minggu yang sama (Minggu=0, Senin=1, dst)
date.setDate(date.getDate() + 3 - (date.getDay() + 6) % 7);
// Ambil tanggal 4 Januari dari tahun yang udah digeser (pasti masuk minggu 1)
const week1 = new Date(date.getFullYear(), 0, 4);
// Hitung selisih hari, lalu bagi 7 dapet deh minggu ke berapa
return 1 + Math.round(((date.getTime() - week1.getTime()) / 86400000 - 3 + (week1.getDay() + 6) % 7) / 7);
}
// Nampilin data hari ini pas halaman diload
const today = new Date();
const currentWeek = getWeekNumber(today);
// (Asumsi kamu punya elemen dengan id 'current-week')
// document.getElementById('current-week').innerText = currentWeek;
// Bikin format tanggalnya lebih manusiawi (bahasa Indo)
const options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
// document.getElementById('current-date-info').innerText = today.toLocaleDateString('id-ID', options);
// Dengerin perubahan di kotak input tanggal
const dateInput = document.getElementById('custom-date');
const customResult = document.getElementById('custom-result');
if(dateInput && customResult) {
dateInput.addEventListener('change', function(e) {
if (this.value) {
const selectedDate = new Date(this.value);
const weekNum = getWeekNumber(selectedDate);
customResult.innerText = `Mantap, tanggal itu masuk di minggu ke-${weekNum} lur!`;
} else {
customResult.innerText = '';
}
});
}
</script>Bedah Kode: Bagaimana Algoritma Ini Bekerja?
Melihat kode matematika berbasis waktu memang kadang bikin sakit mata. Namun, mari kita bedah pelan-pelan logika dari fungsi getWeekNumber() di atas agar kamu paham dasar mekanismenya.
1. Pengamanan Referensi dan Zona Waktu
Di awal blok fungsi, kita membuat instansi Date baru. Ini wajib dilakukan agar objek tanggal asli yang kita masukkan tidak ikut berubah secara tak sengaja (mutasi). Selanjutnya, kita me-reset waktu menjadi 00:00:00. Tujuannya murni defensif: untuk mencegah kalkulasi hari meleset gara-gara perubahan Daylight Saving Time (DST) atau perbedaan zona waktu lokal di mesin client.
2. Matematika "Menggeser ke Kamis"
Kunci utama dari standar ISO 8601 adalah hari Kamis. Perintah date.setDate(date.getDate() + 3 - (date.getDay() + 6) % 7); bertugas memaksa kalender untuk menggeser tanggal ke hari Kamis pada minggu yang sama. Dengan kalkulasi modulus ini, baik kamu memasukkan hari Senin maupun Minggu, pointer tanggal akan otomatis terkunci di posisi hari Kamis.
3. Patokan Abadi: 4 Januari
Mengapa tiba-tiba muncul tanggal 4 Januari di baris const week1 = new Date(date.getFullYear(), 0, 4);? Ini adalah trik legendaris para programmer.
Berdasarkan rumusan ISO, hari Kamis pertama selalu jatuh antara tanggal 1 hingga 7 Januari. Artinya, tanggal 4 Januari selalu masuk ke dalam wilayah minggu pertama, apa pun yang terjadi pada tahun tersebut. Dengan menjadikan 4 Januari sebagai titik start absolut (Minggu 1), kita tinggal menghitung selisih milidetik dari tanggal yang kita cari terhadap patokan tersebut.
4. Kalkulasi Milidetik ke Angka Minggu
Langkah terakhir adalah murni matematika anak SD. Kita mengurangi milidetik tanggal yang dicari dengan milidetik tanggal 4 Januari. Hasilnya dibagi 86400000 (jumlah milidetik dalam sehari) untuk mendapatkan total hari. Selisih hari tersebut tinggal dibagi tujuh, lalu ditambah satu. Boom! Keluarlah hasil ISO Week Number yang sangat presisi.
Integrasi Interaktif ke DOM HTML
Pada paruh kedua script tersebut, saya juga menyisipkan logika interaktif. Ketika user memilih tanggal di kotak kalender buatan (berbasis input type date), fungsi addEventListener('change') akan langsung menangkap data value tersebut, memprosesnya kembali melalui mesin getWeekNumber(), dan mencetak hasilnya secara langsung (real-time) tanpa perlu memuat ulang halaman.
Penggunaan metode bawaan toLocaleDateString('id-ID', options) juga sangat direkomendasikan untuk mencetak format tanggal lokal yang lebih ramah dibaca manusia secara native. Nggak perlu pusing lagi kan kalau dapet tugas aneh-aneh terkait kalender?