Chapter sebelumnya ditutup dengan teka-teki: log mencatat Jan 15, padahal kita orang Indonesia — siapa yang memutuskan tanggal itu ditulis dalam bahasa Inggris? Jawabannya ada dua pengaturan yang sering tertukar: locale mengatur bahasa dan format (nama hari, format angka, urutan sort), sedangkan timezone mengatur jam dinding yang diikuti sistem. Dua-duanya bisa berbeda antar mesin dan dua-duanya menentukan apa yang kita lihat di layar. Chapter ini membedah keduanya satu per satu, dari prioritas variabel lingkungan hingga zona waktu Indonesia yang membentang tiga jam.
Locale: Aturan Bahasa dan Format #
Locale bukan sekadar penerjemah pesan sistem. Satu locale adalah sekelompok aturan yang mengatur bagaimana software memformat hampir semua yang berhadapan dengan manusia:
| Kategori | Yang diatur |
|---|---|
LC_CTYPE | klasifikasi huruf, huruf besar-kecil |
LC_NUMERIC | pemisah desimal dan ribuan (1.000,50 vs 1000.50) |
LC_TIME | nama hari dan bulan, urutan tanggal |
LC_COLLATE | urutan sort string |
LC_MONETARY | format mata uang |
LC_MESSAGES | bahasa pesan program |
Nilai-nilai itu dibaca dari variabel lingkungan dengan urutan prioritas yang ketat: LC_ALL menimpa kategori LC_* satu per satu, dan LANG hanya menjadi nilai bawaan untuk kategori yang variabel LC_*-nya tidak di-set. Perintah locale menampilkan keadaan lengkapnya:
localeOutput yang Dihasilkan:
LANG=C.UTF-8
LANGUAGE=
LC_CTYPE="C.UTF-8"
LC_NUMERIC="C.UTF-8"
LC_TIME="C.UTF-8"
LC_COLLATE="C.UTF-8"
LC_MONETARY="C.UTF-8"
LC_MESSAGES="C.UTF-8"
LC_PAPER="C.UTF-8"
LC_NAME="C.UTF-8"
LC_ADDRESS="C.UTF-8"
LC_TELEPHONE="C.UTF-8"
LC_MEASUREMENT="C.UTF-8"
LC_IDENTIFICATION="C.UTF-8"
LC_ALL=C.UTF-8Tampilan itu memuat tiga lapis informasi yang layak dibaca cermat:
LANG=C.UTF-8: nilai bawaan sistem latihan ini — locale netralCdengan pengodean UTF-8, satu-satunya yang dijamin ada di semua instalasi.LANGUAGE=: kosong — variabel tambahan milik GNU untuk daftar preferensi bahasa, dipakai oleh program berbasis GNU gettext.LC_CTYPE="C.UTF-8"dan kawan-kawannya dalam tanda kutip: variabelLC_*ini tidak di-set satu per satu; nilai di dalam kutip adalah nilai efektif yang mereka terima dariLC_ALL. BandingkanLC_ALL=C.UTF-8di baris terakhir yang tampil tanpa kutip karena variabelnya memang di-set langsung.
Untuk melihat semua locale yang tersedia di sistem, kita pakai locale -a:
locale -aOutput yang Dihasilkan:
C
C.utf8
POSIXSistem latihan minimal ini hanya mengenal C, C.utf8, dan POSIX — tiga nama untuk keluarga locale netral yang sama. Desktop dan server yang kita kelola biasanya jauh lebih kaya.
Memasang Locale Baru dengan locale-gen #
Locale tambahan di Debian datang dari paket locales. Caranya: buka file /etc/locale.gen, hapus tanda # di depan baris yang diinginkan (misalnya id_ID.UTF-8 UTF-8), lalu jalankan sudo locale-gen — perintah ini men-generate data locale dari template dan menambahkannya ke daftar locale -a. Cara interaktifnya adalah sudo dpkg-reconfigure locales, sedangkan pengaturan permanen untuk seluruh sistem disimpan di /etc/default/locale.
Setelah id_ID.UTF-8 tersedia, efeknya langsung terasa di semua program yang patuh locale. Berikut contoh tampilan date yang sama dijalankan dengan locale Indonesia:
$ LC_ALL=id_ID.UTF-8 date -d "2026-01-15" "+%A, %d %B %Y"
Kamis, 15 Januari 2026
Bandingkan dengan locale C yang menghasilkan Thursday, 15 January 2026 — tanggal yang sama, dinding yang sama, hanya bahasanya yang berganti. Prefix LC_ALL=... di depan perintah berlaku untuk perintah itu saja, pola yang sama dengan TZ= yang akan kita pakai sebentar lagi.
Timezone: zoneinfo dan /etc/localtime #
Zona waktu Linux tidak diambil dari firasat — semuanya berasal dari database IANA yang tersimpan di /usr/share/zoneinfo: satu file biner per zona (misalnya Asia/Jakarta) berisi seluruh aturan sejarahnya, termasuk kapan Indonesia pernah berubah batas zona. Pilihan zona sistem ditandai oleh satu symlink, /etc/localtime, yang menunjuk ke file zona pilihan:
readlink /etc/localtime
ls /usr/share/zoneinfo/Asia/ | grep -E 'Jakarta|Jayapura'Output yang Dihasilkan:
/usr/share/zoneinfo/Etc/UTC
Jakarta
JayapuraBaris pertama menunjukkan sistem latihan ini berjalan di zona Etc/UTC; di server produksi kita, symlink semacam ini yang kita ganti untuk memindahkan zona. Baris kedua memastikan dua zona Indonesia tersedia di database: Jakarta dan Jayapura. Zona ketiga untuk WITA bernama Makassar — ketiganya tinggal dipilih sesuai wilayah, dan daftar seluruh kota lainnya diperoleh dengan ls /usr/share/zoneinfo/Asia/. Mekanisme symlink ini sudah kita bahas di Symbolic Links dan Hard Links
, dan Debian juga menyimpan salinan teks zona di file /etc/timezone sebagai referensi manusia.
Alat resmi systemd untuk mengatur semuanya adalah timedatectl. Berikut contoh tampilan statusnya di server dengan zona Jakarta:
Local time: Thu 2026-01-15 15:30:05 WIB
Universal time: Thu 2026-01-15 08:30:05 UTC
RTC time: Thu 2026-01-15 08:30:05
Time zone: Asia/Jakarta (WIB, +0700)
System clock synchronized: yes
NTP service: active
RTC in local TZ: noPerhatikan baris Local time dan Universal time: satu momen yang sama, dua jam dinding yang berbeda — persis topik penutup kita. Perintah pengaturannya lugas: timedatectl set-timezone Asia/Jakarta mengganti zona (dan otomatis memperbarui /etc/localtime serta /etc/timezone), timedatectl list-timezones menampilkan semua kandidat, dan timedatectl set-ntp true menyalakan sinkronisasi waktu otomatis. Di container latihan tanpa systemd sebagai PID 1, timedatectl menolak bekerja — persis kelakuan systemctl dan journalctl yang sudah kita jumpai di section Systemd dan Services
.
Jam yang Sama, Dinding yang Berbeda #
Indonesia membentang tiga zona: WIB (UTC+7) untuk wilayah barat, WITA (UTC+8) untuk tengah, dan WIT (UTC+9) untuk timur. Satu momen ditampilkan dengan tiga jam dinding — dan date mampu menunjukkan ketiganya sekaligus untuk waktu contoh yang kita kunci:
printf 'UTC: %s\n' "$(date -u -d '2026-01-15 08:30' '+%F %T')"
printf 'Jakarta: %s\n' "$(TZ=Asia/Jakarta date -d '2026-01-15 08:30 UTC' '+%F %T %Z')"
printf 'Jayapura: %s\n' "$(TZ=Asia/Jayapura date -d '2026-01-15 08:30 UTC' '+%F %T %Z')"Output yang Dihasilkan:
UTC: 2026-01-15 08:30:00
Jakarta: 2026-01-15 15:30:00 WIB
Jayapura: 2026-01-15 17:30:00 WITBedah ketiga barisnya:
- Baris 1:
date -umenampilkan waktu dalam UTC —08:30:00tanpa zona, karena-umemaksa jam dinding UTC. - Baris 2: prefix
TZ=Asia/Jakartamenyetel zona untuk perintahdateini saja, dan sufiksUTCdi dalam string tanggal memberi tahudatebahwa08:30yang kita tulis adalah jam UTC. Hasil konversinya:15:30:00 WIB— tujuh jam lebih cepat. - Baris 3: momen yang sama dengan zona Jayapura menghasilkan
17:30:00 WIT, sembilan jam di depan UTC.
Untuk zona yang menetap lebih lama, simpan export TZ=Asia/Jayapura di ~/.bashrc — hanya user itu yang terpengaruh, sistem tetap pada /etc/localtime. Referensi lengkap mekanisme locale ada di locale(7)
, format output date di date(1)
, dan sub-perintah timedatectl di timedatectl(1)
.
Kita kini bisa mengatur jam dinding, tetapi satu pertanyaan masih tersisa: bagaimana sistem menjaga jam itu tetap akurat berhari-hari, dan bagaimana date dipakai untuk menampilkan serta menggeser waktu? Itu tugas chapter berikutnya tentang date dan sinkronisasi waktu NTP.