Berikut ini adalah skrip Ruby yang saya tulis untuk mengubah konfigurasi zona waktu di Ubuntu. Saya menjalankannya dengan jruby (penerjemah Ruby yang berjalan di JVM).
require 'java'
if ARGV.length == 0
puts "Usage: jruby change_timezone.rb America/Toronto"
exit
end
old_zone = File.read("../../../etc/timezone")
puts old_zone
time1 = Time.now
puts "Current Time:"+time1.localtime.to_s
new_zone = ARGV[0]
open('../../../etc/timezone','w') do |f|
f.puts new_zone.to_s
f.close
end
new_zone = File.read("../../../etc/timezone")
puts new_zone
time2 = Time.now
puts "Updated Time:"+time2.localtime.to_s
Itu mengubah file konfigurasi dengan benar. Namun, keluaran untuk skrip tersebut tidak seperti yang diharapkan.
Asumsikan nilai default untuk zona waktu adalah America/Toronto
.
Saat saya menjalankan perintah jruby change_timezone.rb Asia/Chongqing
, outputnya adalah:
America/Toronto
Current Time:Thu Jul 07 14:43:23 -0400 2011
Asia/Chongqing
Updated Time:Thu Jul 07 14:43:23 -0400 2011 (My Note: +0800 expected!!!)
Dilanjutkan dengan perintah jruby change_timezone.rb Europe/Amsterdam
, saya berakhir dengan yang berikut:
Asia/Chongqing
Current Time:Fri Jul 08 03:18:25 +0800 2011 (My Note: it actually got updated from last run!!!)
Europe/Amsterdam
Updated Time:Fri Jul 08 03:18:25 +0800 2011 (My Note: +0200 expected!!!)
Melangkah lebih jauh dengan jruby change_timezone.rb Europe/Amsterdam
lagi, saya mendapatkan yang berikut:
Europe/Amsterdam
Current Time:Thu Jul 07 21:21:27 +0200 2011
Europe/Amsterdam
Updated Time:Thu Jul 07 21:21:27 +0200 2011
Dapatkah seseorang mencari tahu mengapa itu tidak bekerja seperti yang diharapkan?
Jawaban yang Diterima:
Ini adalah masalah bagaimana Java menentukan zona waktu di bawah sistem unix.
Spesifikasi POSIX tidak menentukan cara menentukan zona waktu saat TZ
variabel lingkungan tidak disetel. Saya tidak dapat menemukan apa pun di Basis Standar Linux tentang ini.
Pustaka sistem dasar (GNU libc) menggunakan /etc/localtime
untuk menentukan zona waktu. Jadi pada Linux non-embedded, /etc/localtime
adalah tempat informasi zona waktu disimpan, dan idealnya cerita akan berakhir di sini.
(Melihat-lihat:FreeBSD, NetBSD dan OpenBSD menggunakan /etc/localtime
. Solaris dan beberapa lainnya menggunakan /etc/TIMEZONE
. Batu Rosetta untuk Unix menunjukkan apa yang digunakan oleh unice lainnya. Dietlibc (digunakan di beberapa sistem Linux tertanam) menggunakan /etc/localtime
, sedangkan uClibc menggunakan /etc/TZ
(kecuali ditambal).)
Sayangnya, Java melakukan hal yang berbeda. Debian dan Ubuntu memiliki file bernama /etc/timezone
yang berisi nama zona waktu. File tambahan ini ditujukan untuk sistem pengemasan, sehingga mengingat nama geografis seperti Europe/Amsterdam
bukan hanya deskripsi zona waktu (offset dari waktu ke waktu, dan menampilkan nama CET
, CEST
dan CEDT
). Ini lebih ramah bagi manusia dan kuat jika lokasi geografis memperbarui aturan zona waktunya. Sun (sekarang Oracle) Java lebih menyukai /etc/timezone
(atau /etc/sysconfig/clock
pada distribusi berbasis Red Hat) lihat bug #6456628 hingga /etc/localtime
, dan OpenJDK dan gcj mengikutinya.
Solusinya sederhana:selalu perbarui /etc/timezone
dan /etc/localtime
bersama. Di Debian atau Ubuntu, metode resmi untuk mengubah zona waktu adalah dpkg-reconfigure tzdata
. Untuk mengubah zona waktu hanya untuk satu aplikasi, setel TZ
variabel lingkungan (ini portabel di semua sistem unix).