Force Timezone in Javascript Date
So I was working on a project for which I needed to force the Eastern timezone while displaying dates. Though not relevant to the post, I thought I need to share a few words about the method I chose to accomplish the task. I discovered prototype object (not the framework) today. (You are welcome to skip this section and proceed to the implementation) Here is an excerpt from the excellent Mozilla Development Network pages:
All objects in JavaScript are descended from Object; all objects inherit methods and properties from Object.prototype, although they may be overridden (except an Object with a null prototype, i.e. Object.create(null)). For example, other constructors’ prototypes override the constructor property and provide their own toString methods. Changes to the Object prototype object are propagated to all objects unless the properties and methods subject to those changes are overridden further along the prototype chain.
The items we are interested in are:
- they may be overriden
- changes are propogated to all objects
This is applicable to both user defined types and built-in types in javascript. This is awesome! I decided to use the Object.prototype
object to extend the built-in Date type to add some sugar to my code while keeping it readable.
if (!Date.prototype.getStandardTimezoneOffset) {
// method to return the timezone offset when DST is off
Date.prototype.getStandardTimezoneOffset = function () {
// this logic will fail if DST is observed on both the dates picked below
// but as far as I can tell there are no such timezones
var jan = new Date(this.getFullYear(), 0, 1);
var jul = new Date(this.getFullYear(), 6, 1);
return Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset());
}
}
if (!Date.prototype.isDst) {
// method to check if DST is in effect or not
Date.prototype.isDst = function () {
return this.getTimezoneOffset() < this.getStandardTimezoneOffset();
}
}
function getEastern(sourceDatetime) {
// offset is in minutes, so to convert to milliseconds, we use the following conversion factor
var OFFSET_IN_MILLIS = 1000 * 60;
// now lets define the eastern timezone offset
var easternOffset = -5 * 60 * OFFSET_IN_MILLIS;
if (sourceDatetime.isDst()) {
easternOffset = -4 * 60 * OFFSET_IN_MILLIS;
}
// get current timezone offset
var userOffset = sourceDatetime.getTimezoneOffset() * OFFSET_IN_MILLIS;
// eastern time = current time + user offset + eastern offset
return new Date(sourceDatetime.getTime() + userOffset + easternOffset);
}
Notice the extension of the built-in Date by the addition of getStandardTimezoneOffset()
and isDst()
methods. Also notice how getEastern(datetime)
is not an extension but just a straight up javascript function since it is a very specific use case and it makes no sense to make this function available to all instances of Date.
The code is pretty self explanatory but if you have questions drop me a note and I’ll do my best to answer them. Accomplishing this task and this post would not be complete without posting references to the articles that guided me through this process.