JavaScript Code to Determine When DayLight Savings Time (DST) Occurs






3.88/5 (11 votes)
JavaScript code to determine when DayLight Savings Time (DST) occurs
Introduction
Sometimes, you need to be able to determine when Daylight Savings Time (DST) will occur in a given year. DST varies around the world for timezones where DST is observed. The code herein can automatically determine the date/time a minute before a DST change occurs in the user's timezone. The JavaScript Date
object is used as part of calculating the date/time just before DST adjustments occur. I needed a solution with this behavior to properly adjust UTC date/time for previous and future dates intended for display to users. Feel free to adapt the code for your own uses.
Using the Code
The DST determination is split between two functions. The DisplayDstSwitchDates()
function locates the initial date/time for each month before a timezone
change occurs. This method internally calls the FindDstSwitchDate()
method, which in turn determines the exact minute before a timezone
change occurs.
To elaborate more on the code, let's first take a look at the DisplayDstSwithDates()
function. This function is very simple. Its only purpose is to get the date/time from 12 consecutive months and compare the timezone
offset month to month. When the timezone
changes, the month prior to the current date/time checked is captured. Typically, there are two times the timezone
will change if the code is running on a browser running in a geographical location where DST is observed. The for
loop completes once the month counter (variable i
) reaches 12
. With the current year and the two month numbers captured, the FindDstSwitchDate()
function is called.
The FindDstSwitchDate()
function may appear busy, but it is actually very simple. The first part of the function starts checking the timezone
offset day by day, beginning with the month and year supplied as function parameters. Once the timezone
offset changes, the day prior to the timezone
offset change is captured. The rest of the function counts minute by minute, beginning with the day captured, until the timezone
offset changes. The minute prior to the actual date/time that the timezone
offset changes is captured. Using the captured day and number of minutes, the function assembles a string
to represent the date/time that is one minute prior to when a timezone
offset change occurs. This function is called twice for locations where DST is observed. One date represents a minute before when you turn the clock back an hour, and the other date represents a minute before when you move the clock ahead by an hour.
If you would like to learn more about DST and see the applicable DST rules for countries around the world, please have a look here: time and date.com DST information.
<!DOCTYPE html>
<html>
<head>
<title>DST Calculator</title>
<script type="text/javascript">
function DisplayDstSwitchDates()
{
var year = new Date().getYear();
if (year < 1000)
year += 1900;
var firstSwitch = 0;
var secondSwitch = 0;
var lastOffset = 99;
// Loop through every month of the current year
for (i = 0; i < 12; i++)
{
// Fetch the timezone value for the month
var newDate = new Date(Date.UTC(year, i, 0, 0, 0, 0, 0));
var tz = -1 * newDate.getTimezoneOffset() / 60;
// Capture when a timzezone change occurs
if (tz > lastOffset)
firstSwitch = i-1;
else if (tz < lastOffset)
secondSwitch = i-1;
lastOffset = tz;
}
// Go figure out date/time occurrences a minute before
// a DST adjustment occurs
var secondDstDate = FindDstSwitchDate(year, secondSwitch);
var firstDstDate = FindDstSwitchDate(year, firstSwitch);
if (firstDstDate == null && secondDstDate == null)
return 'Daylight Savings is not observed in your timezone.';
else
return 'Last minute before DST change occurs in ' +
year + ': ' + firstDstDate + ' and ' + secondDstDate;
}
function FindDstSwitchDate(year, month)
{
// Set the starting date
var baseDate = new Date(Date.UTC(year, month, 0, 0, 0, 0, 0));
var changeDay = 0;
var changeMinute = -1;
var baseOffset = -1 * baseDate.getTimezoneOffset() / 60;
var dstDate;
// Loop to find the exact day a timezone adjust occurs
for (day = 0; day < 50; day++)
{
var tmpDate = new Date(Date.UTC(year, month, day, 0, 0, 0, 0));
var tmpOffset = -1 * tmpDate.getTimezoneOffset() / 60;
// Check if the timezone changed from one day to the next
if (tmpOffset != baseOffset)
{
var minutes = 0;
changeDay = day;
// Back-up one day and grap the offset
tmpDate = new Date(Date.UTC(year, month, day-1, 0, 0, 0, 0));
tmpOffset = -1 * tmpDate.getTimezoneOffset() / 60;
// Count the minutes until a timezone change occurs
while (changeMinute == -1)
{
tmpDate = new Date(Date.UTC(year, month, day-1, 0, minutes, 0, 0));
tmpOffset = -1 * tmpDate.getTimezoneOffset() / 60;
// Determine the exact minute a timezone change
// occurs
if (tmpOffset != baseOffset)
{
// Back-up a minute to get the date/time just
// before a timezone change occurs
tmpOffset = new Date(Date.UTC(year, month,
day-1, 0, minutes-1, 0, 0));
changeMinute = minutes;
break;
}
else
minutes++;
}
// Add a month (for display) since JavaScript counts
// months from 0 to 11
dstDate = tmpOffset.getMonth() + 1;
// Pad the month as needed
if (dstDate < 10) dstDate = "0" + dstDate;
// Add the day and year
dstDate += '/' + tmpOffset.getDate() + '/' + year + ' ';
// Capture the time stamp
tmpDate = new Date(Date.UTC(year, month,
day-1, 0, minutes-1, 0, 0));
dstDate += tmpDate.toTimeString().split(' ')[0];
return dstDate;
}
}
}
</script>
</head>
<body>
<script type="text/javascript">
document.write("Current date/time: " + new Date() + "<br />");
document.write(DisplayDstSwitchDates());
</script>
</body>
</html>
Points of Interest
Please note that capturing the date/time one minute before a timezone
change occurs is purposeful in that if you try to capture the date/time one minute later, you'll find that JavaScript applies the DST time adjustment (moves the hour ahead or backward). I am open to constructive criticism, suggestions, and requests, so please provide feedback.
History
- v1.0: 02-14-2010: Initial post
- v1.1: 02-14-2010: Added additional explanations for the code
- v1.2: 02-18-2010: Added a conditional to add 1900 to the year to accommodate Firefox, Chrome, and perhaps other browsers