Here is a ruby script I wrote to change the timezone configuration on Ubuntu. I run it with jruby (a Ruby interpreter running in a 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
It does change the configuration file properly. However, the output for the script is not as expected.
Assume the default value for the timezone is America/Toronto.
When I run the command jruby change_timezone.rb Asia/Chongqing, the output is:
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!!!)
Continuing with the command jruby change_timezone.rb Europe/Amsterdam, I end up with the following:
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!!!)
Going further with jruby change_timezone.rb Europe/Amsterdam again, I get the following:
Europe/Amsterdam Current Time:Thu Jul 07 21:21:27 +0200 2011 Europe/Amsterdam Updated Time:Thu Jul 07 21:21:27 +0200 2011
Can someone figure out why it didn’t work as expected?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
This is an issue in how Java determines the time zone under unix systems.
The POSIX specification does not specify how to determine the timezone when the TZ environment variable is not set. I can’t find anything in the Linux Standard Base about this.
The base system library (GNU libc) uses /etc/localtime to determine the timezone. So on non-embedded Linux, /etc/localtime is where the timezone information is stored, and ideally the story would end here.
(Looking around: FreeBSD, NetBSD and OpenBSD use /etc/localtime. Solaris and a few others use /etc/TIMEZONE. The Rosetta Stone for Unix shows what other unices use. Dietlibc (used in some embedded Linux systems) uses /etc/localtime, while uClibc uses /etc/TZ (unless patched).)
Unfortunately, Java does things differently. Debian and Ubuntu have a file called /etc/timezone which contains the name of the timezone. This extra file is intended for the packaging system, so that it remembers a geographical name like Europe/Amsterdam rather than just the description of the timezone (offsets over time, and display names CET, CEST and CEDT). This is both friendlier to humans and robust in case the geographical locale updates its time zone rules. Sun (now Oracle) Java prefers /etc/timezone (or /etc/sysconfig/clock on Red Hat-based distributions) see bug #6456628 to /etc/localtime, and OpenJDK and gcj follow suit.
See also: How do I find the current system timezone?; Java Time Zone is messed up.
The solution is simple: always update /etc/timezone and /etc/localtime together. On Debian or Ubuntu, the official method to change the timezone is dpkg-reconfigure tzdata. To change the timezone only for one application, set the TZ environment variable (this is portable across all unix systems).
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0