When talking time zones: Bogota != Eastern Time (US & Canada)!
I’ve been using the timezone localization technique of asking the browser when the page loads what the browsers timezone offset from UTC is, and posting that back to the server and storing it in the session. Â However recently I noticed that with the event of Daylight Savings Time, this was no longer working, because my time would come up an hour off here in Virginia.
After much faffing about, I finally figured it out. Â On the server I would ask for the set of timezones that matched the offset, and grab the first one and put that in the session:
[sourcecode]
result = ActiveSupport::TimeZone.all.select{|t|t.utc_offset == gmtoffset}.first
session[:time_zone] = result.name
[/sourcecode]
The list of named time zones returned when the browser is in Charlottesville, Virginia are: Bogota, Eastern Time (US & Canada), Indiana (East), Lima, Quito.
So when I use Bogota as the timezone, and ask Rails to show the time localized:
[ruby]
Time.now.in_time_zone(session[:time_zone])
[/ruby]
I get back the time without taking into account daylight savings wrong. I started trying to figure out if the browser was in a DST zone using this JavaScript code: http://www.michaelapproved.com/articles/daylight-saving-time-dst-detect/ and while it seems very promising, it still wasn’t quite giving me what I want.
Finally, I realized it…. By arbitrarily grabbing the first time zone in the list, I was showing time in Bogota, Columbia. But if I chose Eastern Time (US & Canada) then I do get a localized time that takes into account day light savings!
So right now I have this method:
[ruby]
result = ActiveSupport::TimeZone.all.select{|t| t.utc_offset == gmtoffset && t.name.include?("US")}.first
session[:time_zone] = result.name
[/ruby]
Obviously this is pretty hardcoded to just work in the US, and isn’t a real solution. I’d love to hear other ideas! Part of me wonders if I should just display all times in UTC in HTML, and have some sort of client side JavaScript that localizes the time display?
My full set of code:
Javascript in my index.html.erb view:
[javascript]
// Calls the server and sets the user’s time.
Event.observe(window, ‘load’, function(e) {
var now = new Date();
var gmtoffset = TimezoneDetect();
//use ajax to set the time zone here.
var set_time = new Ajax.Request(‘<%=url_for :controller => "home", :action => "gmtoffset"%>?gmtoffset=’+gmtoffset, {
onSuccess: function(transport) {
//alert("Response" + transport.responseText);
}
});
});
// http://www.michaelapproved.com/articles/daylight-saving-time-dst-detect/
function TimezoneDetect(){
var dtDate = new Date(’1/1/’ + (new Date()).getUTCFullYear());
var intOffset = 10000; //set initial offset high so it is adjusted on the first attempt
var intMonth;
var intHoursUtc;
var intHours;
var intDaysMultiplyBy;
//go through each month to find the lowest offset to account for DST
for (intMonth=0;intMonth < 12;intMonth++){
//go to the next month
dtDate.setUTCMonth(dtDate.getUTCMonth() + 1);
//To ignore daylight saving time look for the lowest offset.
//Since, during DST, the clock moves forward, it’ll be a bigger number.
if (intOffset > (dtDate.getTimezoneOffset() * (-1))){
intOffset = (dtDate.getTimezoneOffset() * (-1));
}
}
return intOffset;
}
[/javascript]
home_controller.rb action:
[ruby]
def gmtoffset
gmtoffset = params[:gmtoffset].to_i*60 if !params[:gmtoffset].nil? # notice that the javascript version of gmtoffset is in minutes
result = ActiveSupport::TimeZone.all.select{|t| t.utc_offset == gmtoffset && t.name.include?("US")}.first
session[:time_zone] = result.name
render :update do |page|
page.replace_html ‘time_of_chat_starting’, :partial=> ‘super_short_time’
page.visual_effect :highlight, ‘time_of_chat_starting’
end
end
[/ruby]
Rendered partial helper view _super_short_time.erb:
[ruby]
<%= super_short_time(Time.now.in_time_zone(session[:time_zone])) %>
[/ruby]
About Eric Pugh
Fascinated by the “craft” of software development, Eric Pugh has been heavily involved in the open source world as a developer, committer, and user for the past 5 years. He is an emeritus member of the Apache Software Foundation and lately has been mulling over how we move from the read/write web to the read/write/share web.
In biotech, financial services and defense IT, he has helped European and American companies develop coherent strategies for embracing open source software. As a speaker he has advocated the advantages of Agile practices in software development.
Eric became involved in Solr when he submitted the patch SOLR-284 for Parsing Rich Document types such as PDF and MS Office formats that became the single most popular patch as measured by votes! The patch was subsequently cleaned up and enhanced by three other individuals, demonstrating the power of the Free/Open Source Model to build great code collaboratively. SOLR-284 was eventually refactored into Solr Cell as part of Solr version 1.4.
Eric co-authored "Solr 1.4 Enterprise Search Server", the first book on Solr.
He blogs at http://www.opensourceconnections.com/blog/.
More About Eric »Why Attend the NFJS Tour?
- » Cutting-Edge Technologies
- » Agile Practices
- » Peer Exchange
Current Topics:
- Languages on the JVM: Scala, Groovy, Clojure
- Enterprise Java
- Core Java, Java 7
- Agility
- Testing: Geb, Spock, Easyb
- REST
- NoSQL: MongoDB, Cassandra
- Hadoop
- Spring 3
- Automation Tools: Git, Hudson, Sonar
- HTML5, Ajax, jQuery, Usability
- Mobile Applications - iPhone and Android
- More...
NFJS, the Magazine
December Issue Now AvailableBDD and REST
by Brian SlettenMocks and Stubs in Groovy Tests
by Kenneth KousenAlgorithms for Better Text Search Results
by John GriffinKnowns and Unknowns of Scrum and Agile
by Brian Tarbox

