“Time is an illusion. Lunchtime doubly so.” – Ford Prefect
The Hitchhiker’s Guide to the Galaxy by Douglas Adams
Sometimes I wonder if my friends and colleagues across the pond in the US realise just how lucky they are? The majority of application languages are set by default to respect US date and time formats and a host of tools exists to work with these dates and times to calculate offsets and time spans and throw them in and out of databases*.
We in the UK are at best confused and at worst neglected by the developers of software languages provided with contrived and convoluted methods roughly thrust upon us to enable the simplest of date / time conversions.
And I wouldn’t mind but we are home, not just to the historically important Greenwich Mean Time but to the aching arrogance of UNIVERSAL TIME!
That said, ColdFusion makes L10n (or i18n) pretty easy with a host of tools for parsing date and time into native objects (thank you LSParseDateTime() you have saved my bacon on so many occasions) and a well applied understanding that we don’t all like our dates 11/22/2010.
That said there is one area that I was unable to find a native ColdFusion solution for:
I needed to work out the time offset for calculating the time in a given time zone from GMT / UT1 so that I could display the current local time in a different locale. I was surprised, having read through the documentation, to find nothing that would achieve what I needed. Even the normally resourceful ColdFusion Twitterati were at a loss to supply a solution.
Not to be deterred, a quick Google pointed me at a CFC that was created by Sustainable GIS which did exactly what I needed albeit in a slightly overblown manner.
A quick peek under the hood revealed that their CFC was instantiating a native Java class java.util.TimeZone and using that to work out the offset.
I’d encourage anyone with a similar problem to work through the Sustainable GIS CFC and see how they do this calculation properly but for those in need of a quick fix the following example demonstrates my quick and dirty solution:
[cf]
<!— setup our java timezone object —>
<cfset variables.tzObj=createObject("java","java.util.TimeZone")>
<!— need to get the current date time in UTC —>
<cfset variables.currentServerDateTime = parseDateTime(GetHttpTimeString(now())) />
<!— set the timezone we want to offset to —>
<cfset variables.timezone = variables.tzObj.getTimeZone(‘EST’) />
<!— split out and <span class="hiddenSpellError" pre="and ">javacast</span> the date parts used later on to calculate if DST is in effect —>
<cfset variables.tYear=javacast("int",Year(variables.currentServerDateTime)) />
<cfset variables.tMonth=javacast("int",month(variables.currentServerDateTime)-1) />
<cfset variables.tDay=javacast("int",Day(variables.currentServerDateTime)) />
<cfset variables.tDOW=javacast("int",DayOfWeek(variables.currentServerDateTime)) />
<!— <span class="hiddenSpellError" pre="">caculate</span> the offset —>
<cfset variables.myOffset = variables.timezone.getOffset(1,variables.tYear,variables.tMonth,variables.tDay,variables.tDOW,0)/3600000 />
<!— add the hour offset to the current time in UTC —>
<cfset variables.localTime = dateAdd("h",variables.myOffset,variables.currentServerDateTime) />
<cfset variables.myOffsetMinutes = variables.myOffset – fix(variables.myOffset) />
<!— test to see if the offset has minutes as well as hours —>
<cfif variables.myOffsetMinutes gt 0>
<!— we have a minute offset as well —>
<cfset variables.numMins = 60 * variables.myOffsetMinutes />
<!— work out if the offset needs to be positive or negative —>
<cfif variables.myOffset GT 0>
<cfset variables.myMinuteOffset = variables.numMins />
<cfelse>
<cfset variables.myMinuteOffset = 0 – variables.numMins />
</cfif>
<!— apply the minute offset —>
<cfset variables.localTime = dateAdd("n",variables.myMinuteOffset,variables.localTime) />
</cfif>
<cfoutput>
The time in #variables.thisTZ# is #TimeFormat(variables.localTime,"h:mm:ss")#
(Offset of #variables.myOffset# hours from UTC)
</cfoutput>
[/cf]
As I said this is a bit hacky but it works. The original CFC contains more checking and error handling code to work out if the time zone is supported. In this code an unsupported time zone simply returns an offset of 0.
* Tongue firmly in cheek guys and gals I’m aware that the pain of L10n is just as present for those in the States as anywhere else!