Skip to content

Instantly share code, notes, and snippets.

@koseki
Last active June 19, 2017 02:23
Show Gist options
  • Save koseki/c3fca6bf7062d3e2314709596f4b8c40 to your computer and use it in GitHub Desktop.
Save koseki/c3fca6bf7062d3e2314709596f4b8c40 to your computer and use it in GitHub Desktop.
Timezone / Daylight Saving Time aware JavaScript class
/**
* var d = new DateTime(2017, 3, 21, 19, 0, 0, 'JST');
* d.setTimezone('PST');
* console.log(d.format());
*/
var DateTime = (function () {
// Constructor
var DateTime = function(year, month, date, hour, min, sec, tz) {
month = month - 1;
if (!tz) {
tz = 'Z';
}
var input = Date.UTC(year, month, date, hour, min, sec);
var dtsOffset = 0;
if (this.timezones[tz][1]) {
dtsOffset = (this.dtsOffset[this.timezones[tz][1]])(new Date(input));
}
var d = new Date();
this.localOffset = d.getTimezoneOffset() * -60000; // msec
this.setTimezone(tz);
this.utcTime = input - this.zoneOffset - dtsOffset * 3600000;
this.utcDate = new Date(this.utcTime);
}
var p = DateTime.prototype;
p.timezones = {
PST: [-8, 'US'],
CST: [-6, 'US'],
Z: [0, null],
JST: [9, null]
};
p.dtsOffset = {
US: function(localtime) {
var y = localtime.getFullYear();
// the second Sunday in March
var marchFirstDay = new Date(y, 2, 1, 0, 0, 0).getDay(); // 0: Sun, 6: Sat
var startDate;
if (marchFirstDay == 0) {
startDate = 8;
} else {
startDate = 15 - marchFirstDay;
}
startDate = new Date(y, 2, startDate, 2, 0, 0);
var novFirstDay = new Date(y, 10, 1, 0, 0, 0).getDay();
var endDate;
if (novFirstDay == 0) {
endDate = 1;
} else {
endDate = 8 - novFirstDay;
}
endDate = new Date(y, 10, endDate, 3, 0, 0);
var t = localtime.getTime();
if (startDate.getTime() <= t && t < endDate.getTime()) {
return 1;
} else {
return 0;
}
}
}
p.setTimezone = function(tz) {
this.timezone = tz;
this.zoneOffset = this.timezones[tz][0] * 3600000;
this.dtsType = this.timezones[tz][1];
};
p.shiftedDate = function() {
var shiftedTime = this.utcTime - this.localOffset + this.zoneOffset;
var shifted = new Date(shiftedTime);
if (!this.dtsType) {
return shifted;
}
var dtsOffset = this.dtsOffset[this.dtsType](shifted);
shiftedTime = shiftedTime + dtsOffset * 3600000;
return new Date(shiftedTime);
}
p.format = function() {
return this.dateToString(this.shiftedDate());
}
p.dateToString = function(d) {
var pad = function(n) { return n < 10 ? '0' + n : n };
return d.getFullYear()
+ '-' + pad(d.getMonth() + 1)
+ '-' + pad(d.getDate())
+ ' ' + pad(d.getHours())
+ ':' + pad(d.getMinutes());
+ ':' + pad(d.getSeconds());
}
return DateTime;
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment