Menyelesaikan Masalah Time Zone: Kenapa Tampilan Tanggal Berbeda di Production

Lo pernah nggak sih deploy aplikasi web yang berfungsi sempurna ke production, tapi tiba-tiba elemen tanggal dan waktunya tampil nggak bener? Kalau iya, lo nggak sendirian kok. Aspek pengembangan web yang keliatan simpel ini bisa berubah jadi pengalaman debugging yang bikin frustrasi, apalagi kalau lo kerja dengan audiens internasional atau tim yang tersebar di mana-mana.
Gue baru-baru ini ngalamin masalah yang sama pas lagi ngembangain komponen news feed. Aplikasinya berjalan mulus di local development server gue, menampilkan timestamp relatif seperti "2 jam yang lalu" atau "1 hari yang lalu" dalam bahasa Indonesia. Tapi, setelah di-deploy ke production server, timestamp yang sama malah anehnya tampil sebagai "dalam 6 jam" atau menunjukkan waktu yang udah berlalu tapi salah.
Yang tadinya keliatan sebagai fitur simpel berubah jadi bug yang bikin bingung dan ngasih pelajaran penting dalam pengembangan web: jangan pernah anggap remeh time zone.
Jebakan Time Zone
Masalah time zone ini licik banget karena sering nggak muncul sampai aplikasi di-deploy. Environment development lokal lo biasanya pake time zone sistem lo, sementara server production mungkin dikonfigurasi dengan UTC atau time zone lain sepenuhnya. Perbedaan ini menyebabkan perhitungan tanggal yang nggak konsisten, yang berujung pada pengalaman pengguna yang membingungkan.
Untuk aplikasi yang melayani pengguna di wilayah tertentu (seperti Indonesia dalam kasus gue), masalah ini bahkan lebih krusial. Selama event penting seperti Ramadan, timing sangat penting—menampilkan informasi waktu yang salah bisa berdampak signifikan pada kepercayaan pengguna.
Memahami Masalahnya
Sebelum nyemplung ke solusinya, penting buat memahami apa yang sebenernya terjadi dalam masalah terkait time zone:
- Perilaku default: Objek
Date
dalam JavaScript menggunakan time zone lokal dari sistem tempatnya berjalan - Perbedaan environment: Development lo dan server production kemungkinan besar berada di time zone yang berbeda
- Perbedaan perhitungan: Perhitungan waktu relatif (seperti "X jam yang lalu") tergantung pada time zone referensi
- Kompleksitas lokalisasi: Menambahkan lokalisasi bahasa (seperti Bahasa Indonesia) menambahkan lapisan kompleksitas lain
Dalam kasus gue, gue pake Day.js dengan plugin relativeTime
untuk menampilkan tanggal yang diformat dalam Bahasa Indonesia, tapi gue nggak secara eksplisit setting time zone-nya. Ini berarti perhitungan waktu menggunakan referensi yang berbeda di development versus production.
// Kode yang bermasalah
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";
import "dayjs/locale/id";
dayjs.extend(relativeTime);
// Yang kurang: dayjs.locale("id");
// Yang kurang: penanganan timezone
// Penggunaan
<span>{dayjs(publishDate).fromNow()}</span>; // Hasil berbeda di server yang berbeda
Solusinya: Penanganan Time Zone Secara Eksplisit
Kunci untuk menyelesaikan masalah ini adalah dengan eksplisit tentang time zone dalam aplikasi lo. Jangan pernah mengandalkan time zone default sistem, terutama untuk aplikasi yang melayani pengguna di wilayah geografis tertentu.
Berikut solusi komprehensif menggunakan Day.js:
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";
import timezone from "dayjs/plugin/timezone";
import utc from "dayjs/plugin/utc";
import "dayjs/locale/id"; // Locale Indonesia
// Extend Day.js dengan plugin yang diperlukan
dayjs.extend(relativeTime);
dayjs.extend(utc);
dayjs.extend(timezone);
// Set locale dan timezone default
dayjs.locale("id");
dayjs.tz.setDefault("Asia/Jakarta");
// Penggunaan
<span>{dayjs(publishDate).tz("Asia/Jakarta").fromNow()}</span>;
Pendekatan ini memastikan bahwa:
- Semua perhitungan tanggal menggunakan referensi time zone yang sama (Asia/Jakarta dalam kasus ini)
- Locale-nya diatur dengan benar ke Bahasa Indonesia
- Tampilan waktu relatif ditampilkan dengan benar terlepas dari time zone server
Mengimplementasikan Perbaikan di Astro.js
Kalau lo pake Astro.js seperti gue, integrasi solusi ini cukup straightforward. Berikut cara update file komponen lo:
---
import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";
import timezone from "dayjs/plugin/timezone";
import utc from "dayjs/plugin/utc";
import "dayjs/locale/id";
dayjs.extend(relativeTime);
dayjs.extend(utc);
dayjs.extend(timezone);
dayjs.locale("id");
dayjs.tz.setDefault("Asia/Jakarta");
// Props dan logika komponen lo
const { articles } = Astro.props;
---
<div class="articles-container">
{articles.map(article => (
<div class="article-card">
<h3>{article.title}</h3>
<p class="timestamp">{dayjs(article.publishDate).tz("Asia/Jakarta").fromNow()}</p>
<!-- Bagian lain dari article card lo -->
</div>
))}
</div>
Pola ini juga bekerja dengan baik untuk React, Vue, atau framework JavaScript lainnya. Kuncinya adalah menerapkan konfigurasi time zone di awal script komponen lo.
Di Luar Day.js: Pendekatan Lain
Meskipun Day.js menawarkan solusi yang elegan, ada pendekatan lain untuk menangani time zone dalam aplikasi web:
1. Formatting di Server-side
Satu pendekatan alternatif adalah memformat tanggal di server sebelum mengirimkannya ke client:
// Kode server-side (contoh Node.js)
const formatDateForClient = (date) => {
return dayjs(date).tz("Asia/Jakarta").locale("id").fromNow();
};
// Kirim string yang sudah diformat ke client
const articleData = {
// ...field lainnya
formattedDate: formatDateForClient(article.publishDate),
};
Pendekatan ini menghilangkan masalah time zone di client-side sepenuhnya tapi mengorbankan pembaruan dinamis.
2. Menggunakan Intl.RelativeTimeFormat
Untuk browser modern, API native Intl.RelativeTimeFormat
menyediakan pemformatan waktu relatif yang di-internasionalisasi:
function getRelativeTimeString(date, locale = "id") {
// Konversi kedua tanggal ke milidetik
const now = new Date().getTime();
const dateTime = new Date(date).getTime();
// Hitung perbedaan dalam detik
const diffInSeconds = Math.floor((dateTime - now) / 1000);
const absoluteDiff = Math.abs(diffInSeconds);
const formatter = new Intl.RelativeTimeFormat(locale, { numeric: "auto" });
// Format berdasarkan perbedaan waktu
if (absoluteDiff < 60) {
return formatter.format(
Math.sign(diffInSeconds) * Math.floor(absoluteDiff),
"second"
);
} else if (absoluteDiff < 3600) {
return formatter.format(
Math.sign(diffInSeconds) * Math.floor(absoluteDiff / 60),
"minute"
);
} else if (absoluteDiff < 86400) {
return formatter.format(
Math.sign(diffInSeconds) * Math.floor(absoluteDiff / 3600),
"hour"
);
} else {
return formatter.format(
Math.sign(diffInSeconds) * Math.floor(absoluteDiff / 86400),
"day"
);
}
}
// Penggunaan
<span>{getRelativeTimeString(publishDate)}</span>;
Pendekatan ini memiliki dukungan browser yang sangat baik dan nggak perlu library eksternal, tapi implementasinya lebih bertele-tele.
Baca Juga: Menambahkan Header di Image Next.js: Panduan Lengkap
Best Practices untuk Manajemen Time Zone
Berdasarkan pengalaman gue dalam men-debug masalah time zone, berikut beberapa best practices yang bisa lo ikuti:
- Selalu eksplisit soal time zone - Jangan pernah bergantung pada default sistem
- Simpan tanggal dalam format UTC - Untuk penyimpanan database, selalu gunakan UTC dan konversi hanya untuk tampilan
- Pertimbangkan preferensi pengguna - Untuk aplikasi global, izinkan pengguna memilih time zone yang mereka inginkan
- Test di berbagai environment - Uji penanganan tanggal lo di time zone yang berbeda sebelum deployment
- Gunakan library yang sudah established - Library seperti Day.js, date-fns, atau Luxon memiliki penanganan time zone yang teruji dengan baik
- Dokumentasikan pendekatan lo - Buat strategi time zone lo jelas bagi developer lain
Testing Implementasi Time Zone Lo
Setelah mengimplementasikan solusi lo, testing yang menyeluruh sangat penting. Berikut pola test sederhana:
// Tambahkan ini sementara untuk memverifikasi perilaku timezone
console.log(
"System timezone:",
Intl.DateTimeFormat().resolvedOptions().timeZone
);
console.log("Current time (local):", new Date().toString());
console.log("Current time (UTC):", new Date().toUTCString());
console.log(
"Current time (Jakarta):",
dayjs().tz("Asia/Jakarta").format("YYYY-MM-DD HH:mm:ss")
);
console.log(
"Sample relative time:",
dayjs("2025-03-03T12:00:00").tz("Asia/Jakarta").fromNow()
);
Output debugging ini membantu memverifikasi bahwa time zone lo diterapkan dengan benar.
Kesimpulan
Masalah time zone bisa bikin frustrasi banget, terutama ketika masalah itu cuma muncul di production. Dengan mengelola time zone secara eksplisit menggunakan tool seperti Day.js dan plugin timezone-nya, lo bisa memastikan tampilan tanggal dan waktu yang konsisten di semua environment.
Untuk website bertema Ramadan gue, implementasi penanganan time zone yang tepat nggak cuma memperbaiki bug langsung tapi juga meningkatkan pengalaman pengguna secara keseluruhan buat audiens Indonesia kita. Timestamp relatif sekarang dengan benar menampilkan "2 jam yang lalu" atau "kemarin" dalam Bahasa Indonesia, terlepas dari di mana server kita berada.
Inget deh, kalo urusan tanggal dan waktu dalam aplikasi web, jangan pernah bikin asumsi. Be explicit, test dengan teliti, dan pengguna lo akan menikmati pengalaman yang lebih konsisten—nggak peduli di mana pun di dunia mereka (atau server lo) berada.