Created
March 25, 2014 12:10
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!--- | |
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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!--- Create 2:30 AM on Mar 13, 2011. ---> | |
<cfset arizonaMorning = createDateTime( 2011, 3, 13, 2, 30, 0 ) /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!--- | |
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