/** * Bare minimum version of Moment Timezone without dependencies. * * Check Moment Timezone for the original source and data files: * http://momentjs.com/timezone * https://github.com/moment/moment-timezone * * Example of how to use it: * * * */ var mzone = mzone || {}; (function (obj) { "use strict"; obj.loadData = loadData; obj.tz = function (date, tzName) { if (typeof date === "string") { date = new Date(date); } var utc = new Date(date.getTime() + date.getTimezoneOffset() * 60000); var tz = getZone(tzName); if (!tz) { throw "Invalid timezone: " + tzName; } var offset = tz.parse(utc); return new Date(utc.getTime() - offset * 60000); } var zones = {}; var links = {}; var names = {}; function charCodeToInt(charCode) { if (charCode > 96) { return charCode - 87; } else if (charCode > 64) { return charCode - 29; } return charCode - 48; } function unpackBase60(string) { var i = 0, parts = string.split('.'), whole = parts[0], fractional = parts[1] || '', multiplier = 1, num, out = 0, sign = 1; // handle negative numbers if (string.charCodeAt(0) === 45) { i = 1; sign = -1; } // handle digits before the decimal for (var i; i < whole.length; i++) { num = charCodeToInt(whole.charCodeAt(i)); out = 60 * out + num; } // handle digits after the decimal for (var i = 0; i < fractional.length; i++) { multiplier = multiplier / 60; num = charCodeToInt(fractional.charCodeAt(i)); out += num * multiplier; } return out * sign; } function arrayToInt(array) { for (var i = 0; i < array.length; i++) { array[i] = unpackBase60(array[i]); } } function intToUntil(array, length) { for (var i = 0; i < length; i++) { array[i] = Math.round((array[i - 1] || 0) + (array[i] * 60000)); // minutes to milliseconds } array[length - 1] = Infinity; } function mapIndices(source, indices) { var out = [], i; for (i = 0; i < indices.length; i++) { out[i] = source[indices[i]]; } return out; } function unpack(string) { var data = string.split('|'); var offsets = data[2].split(' '); var indices = data[3].split(''); var untils = data[4].split(' '); arrayToInt(offsets); arrayToInt(indices); arrayToInt(untils); intToUntil(untils, indices.length); return { name: data[0], abbrs: mapIndices(data[1].split(' '), indices), offsets: mapIndices(offsets, indices), untils: untils, population: data[5] | 0 }; } function Zone(packedString) { if (packedString) { this._set(unpack(packedString)); } } Zone.prototype = { _set: function (unpacked) { this.name = unpacked.name; this.abbrs = unpacked.abbrs; this.untils = unpacked.untils; this.offsets = unpacked.offsets; this.population = unpacked.population; }, _index: function (timestamp) { var target = +timestamp, untils = this.untils, i; for (i = 0; i < untils.length; i++) { if (target < untils[i]) { return i; } } }, parse: function (timestamp) { var target = +timestamp, offsets = this.offsets, untils = this.untils, max = untils.length - 1, offset, offsetNext, offsetPrev, i; for (i = 0; i < max; i++) { offset = offsets[i]; offsetNext = offsets[i + 1]; offsetPrev = offsets[i ? i - 1 : i]; if (offset < offsetNext) { offset = offsetNext; } else if (offset > offsetPrev) { offset = offsetPrev; } if (target < untils[i] - (offset * 60000)) { return offsets[i]; } } return offsets[max]; }, abbr: function (mom) { return this.abbrs[this._index(mom)]; }, offset: function (mom) { return this.offsets[this._index(mom)]; } }; function normalizeName(name) { return (name || '').toLowerCase().replace(/\//g, '_'); } function addZone(packed) { var i, name, split, normalized; if (typeof packed === "string") { packed = [packed]; } for (i = 0; i < packed.length; i++) { split = packed[i].split('|'); name = split[0]; normalized = normalizeName(name); zones[normalized] = packed[i]; names[normalized] = name; } } function getZone(name, caller) { name = normalizeName(name); var zone = zones[name]; var link; if (zone instanceof Zone) { return zone; } if (typeof zone === 'string') { zone = new Zone(zone); zones[name] = zone; return zone; } // Pass getZone to prevent recursion more than 1 level deep if (links[name] && caller !== getZone && (link = getZone(links[name], getZone))) { zone = zones[name] = new Zone(); zone._set(link); zone.name = names[name]; return zone; } return null; } function addLink(aliases) { var i, alias, normal0, normal1; if (typeof aliases === "string") { aliases = [aliases]; } for (i = 0; i < aliases.length; i++) { alias = aliases[i].split('|'); normal0 = normalizeName(alias[0]); normal1 = normalizeName(alias[1]); links[normal0] = normal1; names[normal0] = alias[0]; links[normal1] = normal0; names[normal1] = alias[1]; } } function loadData(data) { addZone(data.zones); addLink(data.links); } })(mzone);