Skip to content

Instantly share code, notes, and snippets.

@bennadel
Created March 25, 2014 12:10
Show Gist options
  • Save bennadel/9760595 to your computer and use it in GitHub Desktop.
Save bennadel/9760595 to your computer and use it in GitHub Desktop.
Working With Time Zones And Daylight Savings Time (DST) In ColdFusion And Java
<!---
The first thing we want to do is get a list of all the timezone
IDs available in the Java library. So, let's get the library.
--->
<cfset timezoneClass = createObject( "java", "java.util.TimeZone" ) />
<!---
Now, get the IDs. Each ID is a simple string that represents a
specific location, timezone, and daylight savings time
combination. There are an insane number of these combinations!
--->
<cfset timezoneIDs = timezoneClass.getAvailableIDs() />
<!--- Let's output the IDs. --->
<cfoutput>
<cfloop
index="timezoneID"
array="#timezoneIDs#">
#timezoneID#<br />
</cfloop>
</cfoutput>
<!--- Create 2:30 AM on Mar 13, 2011. --->
<cfset arizonaMorning = createDateTime( 2011, 3, 13, 2, 30, 0 ) />
<!---
A lot of our interaction comes through the Timezone class. As
such, let's create a utility instance of it.
--->
<cfset timezoneClass = createObject( "java", "java.util.TimeZone" ) />
<!---
For this demo we are gonna look at two time zones that are
related, but do not honor the same daylight savings time. While
"Mountain Time" is GMT-7, Arizona does not honor daylight savings
time; so, for part of the year, Mountain time is GMT-6 while
Arizona is always GMT-7.
To handle this, Arizona has been given its own timezone ID.
--->
<cfset mountainTimezoneID = "US/Mountain" />
<!--- Arizona's own timezone. --->
<cfset arizonaTimezoneID = "US/Arizona" />
<!--- ----------------------------------------------------- --->
<!--- ----------------------------------------------------- --->
<!---
Now, let's get the actual timezone instances that are responsible
for knowing and powering the rules of date-change in the given
timezone. Each of these can be used with a calendar to drive a
different set of rules and behaviors.
--->
<cfset mountainTimezone = timezoneClass.getTimeZone(
javaCast( "string", mountainTimezoneID )
) />
<!--- Get Arizona's timezone instance. --->
<cfset arizonaTimezone = timezoneClass.getTimeZone(
javaCast( "string", arizonaTimezoneID )
) />
<!--- ----------------------------------------------------- --->
<!--- ----------------------------------------------------- --->
<!---
Now that we have the timezone instances, we are going to
create a Calendar instance using each timezone. This calendar
will allow us to navigate the date/time properties of the
given timezone without running in to any errors that result
from "invalid" dates.
--->
<cfset mountainCalendar = createObject( "java", "java.util.GregorianCalendar" ).init(
mountainTimezone
) />
<!--- Get Arizona's calendar. --->
<cfset arizonaCalendar = createObject( "java", "java.util.GregorianCalendar" ).init(
arizonaTimezone
) />
<!--- ----------------------------------------------------- --->
<!--- ----------------------------------------------------- --->
<!---
Now that we have the calendar instances, we want to test them
to see the rules of date-based augmentation. To do this, we
will start on a day BEFORE daylight savings time and then
increment a day at a time to see how the hours change from
calendar to calendar.
In 2011, daylight savings time started on March 13. As such,
we'll start our dates on March 12 at 2:30 AM and go to March 14.
--->
<cfset beforeDST = createDateTime( 2011, 3, 12, 2, 30, 0 ) />
<!---
Set the mountain time. This takes:
- Year
- Month (NOTE: N - 1 for Java)
- Day
- Hour
- Minute
- Second
NOTE: In the case of Java, months start at zero, not 1
(like ColdFusion).
--->
<cfset mountainCalendar.set(
javaCast( "int", year( beforeDST ) ),
javaCast( "int", (month( beforeDST ) - 1) ),
javaCast( "int", day( beforeDST ) ),
javaCast( "int", hour( beforeDST ) ),
javaCast( "int", minute( beforeDST ) ),
javaCast( "int", second( beforeDST ) )
) />
<!---
Set the milliseonds. If we don't do this, the milliseconds will
continue to roll forward based on the system's clock.
--->
<cfset mountainCalendar.set(
javaCast( "int", mountainCalendar.MILLISECOND ),
javaCast( "int", 0 )
) />
<!--- Set the same start date for Arizona. --->
<cfset arizonaCalendar.set(
javaCast( "int", year( beforeDST ) ),
javaCast( "int", (month( beforeDST ) - 1) ),
javaCast( "int", day( beforeDST ) ),
javaCast( "int", hour( beforeDST ) ),
javaCast( "int", minute( beforeDST ) ),
javaCast( "int", second( beforeDST ) )
) />
<!---
Set the milliseonds. If we don't do this, the milliseconds will
continue to roll forward based on the system's clock.
--->
<cfset arizonaCalendar.set(
javaCast( "int", arizonaCalendar.MILLISECOND ),
javaCast( "int", 0 )
) />
<!--- Now, let's do some testing. --->
<cfoutput>
<strong>Mountain Time</strong><br />
<!--- Show the time for the three days surrounding DST. --->
<cfloop
index="dayOffset"
from="0"
to="2"
step="1">
<!--- Increment the calendar. --->
<cfset mountainCalendar.add(
javaCast( "int", mountainCalendar.DAY_OF_MONTH ),
javaCast( "int", dayOffset )
) />
<!--- Output the time for the current calendar setting. --->
Time:
#mountainCalendar.get( mountainCalendar.HOUR )# :
#mountainCalendar.get( mountainCalendar.MINUTE )#
<!--- Also, output the Epoch offset. --->
(
Epoch:
#mountainCalendar.getTimeInMillis()#
)
<br />
</cfloop>
<!--- For a final comparison, set the HOURS to 3AM. --->
<cfset mountainCalendar.set(
javaCast( "int", mountainCalendar.HOUR ),
javaCast( "int", 3 )
) />
<!--- Output the time for the current calendar setting. --->
Time:
#mountainCalendar.get( mountainCalendar.HOUR )# :
#mountainCalendar.get( mountainCalendar.MINUTE )#
<!--- Also, output the Epoch offset. --->
(
Epoch:
#mountainCalendar.getTimeInMillis()#
)
<br />
<!--- ------------------------------------------------- --->
<br />
<!--- ------------------------------------------------- --->
<strong>Arizona[Mountain] Time</strong><br />
<!--- Show the time for the three days surrounding DST. --->
<cfloop
index="dayOffset"
from="0"
to="2"
step="1">
<!--- Increment the calendar. --->
<cfset arizonaCalendar.add(
javaCast( "int", arizonaCalendar.DAY_OF_MONTH ),
javaCast( "int", dayOffset )
) />
<!--- Output the time for the current calendar setting. --->
Time:
#arizonaCalendar.get( arizonaCalendar.HOUR )# :
#arizonaCalendar.get( arizonaCalendar.MINUTE )#
<!--- Also, output the Epoch offset. --->
(
Epoch:
#arizonaCalendar.getTimeInMillis()#
)
<br />
</cfloop>
<!--- For a final comparison, set the HOURS to 3AM. --->
<cfset arizonaCalendar.set(
javaCast( "int", mountainCalendar.HOUR ),
javaCast( "int", 3 )
) />
<!--- Output the time for the current calendar setting. --->
Time:
#arizonaCalendar.get( arizonaCalendar.HOUR )# :
#arizonaCalendar.get( arizonaCalendar.MINUTE )#
<!--- Also, output the Epoch offset. --->
(
Epoch:
#arizonaCalendar.getTimeInMillis()#
)
<br />
</cfoutput>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment