I mentioned this earlier on Twitter and thought I'd follow up with a quick blog post. This morning I added support for client-side timezone detection in JavaScript. This is specifically built for User Group Managers adding new events to Adobe Groups. The technique is certainly not mine. I read this excellent blog post by Josh Fraser and he deserves all the credit: Auto detect a time zone with JavaScript. I've read his entry twice now and I understand it enough to say I'm darn glad I didn't have to figure it out myself. The rest of this entry will simply focus on how I modified his code to work within the Adobe Group's site.

First off - if you look at Josh's code you will see it is built to look for a drop down in the DOM called timezone. I needed this to be a bit more free form. Adobe Groups is - at heart - a CMS. When editing content I have one generic handler for all types of content - blog posts, events, etc. Therefore there could be multiple, or no, timezone controls on any particular edit page. So the first thing I did was to modify my drop down to use a class I could then pick up within jQuery:

<select name="#arguments.name#_timezone" class="timezonePicker">

The next modification I did was to store the offset and DST settings into the drop down. My option tag already had a value and a label. After getting some advice on Twitter (thanks Ben Nadel) I went with embedding the values using data-KEY form, like so:

<option data-tz="#local.x.getOffset()#,#local.x.getDST()?1:0#" value="#local.x.getId()#" <cfif local.x.getId() is timezone>selected</cfif>>#local.x.getName()#</option>

In case you are curious, local.x is simply a Timezone entity. That's all I changed within the HTML. Here is the JavaScript I ended up using.

<script> // script by Josh Fraser (http://www.onlineaspect.com) $(document).ready(function() { var rightNow = new Date(); var jan1 = new Date(rightNow.getFullYear(), 0, 1, 0, 0, 0, 0); // jan 1st var june1 = new Date(rightNow.getFullYear(), 6, 1, 0, 0, 0, 0); // june 1st var temp = jan1.toGMTString(); var jan2 = new Date(temp.substring(0, temp.lastIndexOf(" ")-1)); temp = june1.toGMTString(); var june2 = new Date(temp.substring(0, temp.lastIndexOf(" ")-1)); var std_time_offset = (jan1 - jan2) / (1000 * 60 * 60); var daylight_time_offset = (june1 - june2) / (1000 * 60 * 60); var dst; if (std_time_offset == daylight_time_offset) { dst = "0"; // daylight savings time is NOT observed } else { // positive is southern, negative is northern hemisphere var hemisphere = std_time_offset - daylight_time_offset; if (hemisphere >= 0) std_time_offset = daylight_time_offset; dst = "1"; // daylight savings time is observed } //find my tz var tzPickers = $(".timezonePicker"); for(var i=0; i<tzPickers.length; i++) { tzPicker = tzPickers[i]; for(var x=0; x<tzPicker.options.length; x++) { var thisData = tzPicker.options[x].getAttribute("data-tz").split(","); if(thisData[0] == std_time_offset && thisData[1] == dst) { tzPicker.selectedIndex = x; break; } } }

}); </script>

So the first portion of this is all Josh. The only change is the second half where I look for all timezonePicker items in the DOM. For each one I loop over their options and see if their data matches the values returned by Josh's code.

I tested this within Chrome, Firefox, and Safari (my primary desktop is Windows but my laptop is still a Mac) and it worked fine. Oddly though (and I didn't test this intensively) it seems like if I changed my timezone settings in the operating system, Chrome would stop picking up on the time zone. I had to restart Chrome in order for it to work again.

Anyway - I hope this helps others - and a big thank you to Josh for making this so simple.