You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
339 lines
7.6 KiB
339 lines
7.6 KiB
//! moment-timezone-utils.js |
|
//! version : 0.5.39 |
|
//! Copyright (c) JS Foundation and other contributors |
|
//! license : MIT |
|
//! github.com/moment/moment-timezone |
|
|
|
(function (root, factory) { |
|
"use strict"; |
|
|
|
/*global define*/ |
|
if (typeof module === 'object' && module.exports) { |
|
module.exports = factory(require('./')); // Node |
|
} else if (typeof define === 'function' && define.amd) { |
|
define(['moment'], factory); // AMD |
|
} else { |
|
factory(root.moment); // Browser |
|
} |
|
}(this, function (moment) { |
|
"use strict"; |
|
|
|
if (!moment.tz) { |
|
throw new Error("moment-timezone-utils.js must be loaded after moment-timezone.js"); |
|
} |
|
|
|
/************************************ |
|
Pack Base 60 |
|
************************************/ |
|
|
|
var BASE60 = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX', |
|
EPSILON = 0.000001; // Used to fix floating point rounding errors |
|
|
|
function packBase60Fraction(fraction, precision) { |
|
var buffer = '.', |
|
output = '', |
|
current; |
|
|
|
while (precision > 0) { |
|
precision -= 1; |
|
fraction *= 60; |
|
current = Math.floor(fraction + EPSILON); |
|
buffer += BASE60[current]; |
|
fraction -= current; |
|
|
|
// Only add buffer to output once we have a non-zero value. |
|
// This makes '.000' output '', and '.100' output '.1' |
|
if (current) { |
|
output += buffer; |
|
buffer = ''; |
|
} |
|
} |
|
|
|
return output; |
|
} |
|
|
|
function packBase60(number, precision) { |
|
var output = '', |
|
absolute = Math.abs(number), |
|
whole = Math.floor(absolute), |
|
fraction = packBase60Fraction(absolute - whole, Math.min(~~precision, 10)); |
|
|
|
while (whole > 0) { |
|
output = BASE60[whole % 60] + output; |
|
whole = Math.floor(whole / 60); |
|
} |
|
|
|
if (number < 0) { |
|
output = '-' + output; |
|
} |
|
|
|
if (output && fraction) { |
|
return output + fraction; |
|
} |
|
|
|
if (!fraction && output === '-') { |
|
return '0'; |
|
} |
|
|
|
return output || fraction || '0'; |
|
} |
|
|
|
/************************************ |
|
Pack |
|
************************************/ |
|
|
|
function packUntils(untils) { |
|
var out = [], |
|
last = 0, |
|
i; |
|
|
|
for (i = 0; i < untils.length - 1; i++) { |
|
out[i] = packBase60(Math.round((untils[i] - last) / 1000) / 60, 1); |
|
last = untils[i]; |
|
} |
|
|
|
return out.join(' '); |
|
} |
|
|
|
function packAbbrsAndOffsets(source) { |
|
var index = 0, |
|
abbrs = [], |
|
offsets = [], |
|
indices = [], |
|
map = {}, |
|
i, key; |
|
|
|
for (i = 0; i < source.abbrs.length; i++) { |
|
key = source.abbrs[i] + '|' + source.offsets[i]; |
|
if (map[key] === undefined) { |
|
map[key] = index; |
|
abbrs[index] = source.abbrs[i]; |
|
offsets[index] = packBase60(Math.round(source.offsets[i] * 60) / 60, 1); |
|
index++; |
|
} |
|
indices[i] = packBase60(map[key], 0); |
|
} |
|
|
|
return abbrs.join(' ') + '|' + offsets.join(' ') + '|' + indices.join(''); |
|
} |
|
|
|
function packPopulation (number) { |
|
if (!number) { |
|
return ''; |
|
} |
|
if (number < 1000) { |
|
return number; |
|
} |
|
var exponent = String(number | 0).length - 2; |
|
var precision = Math.round(number / Math.pow(10, exponent)); |
|
return precision + 'e' + exponent; |
|
} |
|
|
|
function packCountries (countries) { |
|
if (!countries) { |
|
return ''; |
|
} |
|
return countries.join(' '); |
|
} |
|
|
|
function validatePackData (source) { |
|
if (!source.name) { throw new Error("Missing name"); } |
|
if (!source.abbrs) { throw new Error("Missing abbrs"); } |
|
if (!source.untils) { throw new Error("Missing untils"); } |
|
if (!source.offsets) { throw new Error("Missing offsets"); } |
|
if ( |
|
source.offsets.length !== source.untils.length || |
|
source.offsets.length !== source.abbrs.length |
|
) { |
|
throw new Error("Mismatched array lengths"); |
|
} |
|
} |
|
|
|
function pack (source) { |
|
validatePackData(source); |
|
return [ |
|
source.name, // 0 - timezone name |
|
packAbbrsAndOffsets(source), // 1 - abbrs, 2 - offsets, 3 - indices |
|
packUntils(source.untils), // 4 - untils |
|
packPopulation(source.population) // 5 - population |
|
].join('|'); |
|
} |
|
|
|
function packCountry (source) { |
|
return [ |
|
source.name, |
|
source.zones.join(' '), |
|
].join('|'); |
|
} |
|
|
|
/************************************ |
|
Create Links |
|
************************************/ |
|
|
|
function arraysAreEqual(a, b) { |
|
var i; |
|
|
|
if (a.length !== b.length) { return false; } |
|
|
|
for (i = 0; i < a.length; i++) { |
|
if (a[i] !== b[i]) { |
|
return false; |
|
} |
|
} |
|
return true; |
|
} |
|
|
|
function zonesAreEqual(a, b) { |
|
return arraysAreEqual(a.offsets, b.offsets) && arraysAreEqual(a.abbrs, b.abbrs) && arraysAreEqual(a.untils, b.untils); |
|
} |
|
|
|
function findAndCreateLinks (input, output, links, groupLeaders) { |
|
var i, j, a, b, group, foundGroup, groups = []; |
|
|
|
for (i = 0; i < input.length; i++) { |
|
foundGroup = false; |
|
a = input[i]; |
|
|
|
for (j = 0; j < groups.length; j++) { |
|
group = groups[j]; |
|
b = group[0]; |
|
if (zonesAreEqual(a, b)) { |
|
if (a.population > b.population) { |
|
group.unshift(a); |
|
} else if (a.population === b.population && groupLeaders && groupLeaders[a.name]) { |
|
group.unshift(a); |
|
} else { |
|
group.push(a); |
|
} |
|
foundGroup = true; |
|
} |
|
} |
|
|
|
if (!foundGroup) { |
|
groups.push([a]); |
|
} |
|
} |
|
|
|
for (i = 0; i < groups.length; i++) { |
|
group = groups[i]; |
|
output.push(group[0]); |
|
for (j = 1; j < group.length; j++) { |
|
links.push(group[0].name + '|' + group[j].name); |
|
} |
|
} |
|
} |
|
|
|
function createLinks (source, groupLeaders) { |
|
var zones = [], |
|
links = []; |
|
|
|
if (source.links) { |
|
links = source.links.slice(); |
|
} |
|
|
|
findAndCreateLinks(source.zones, zones, links, groupLeaders); |
|
|
|
return { |
|
version : source.version, |
|
zones : zones, |
|
links : links.sort() |
|
}; |
|
} |
|
|
|
/************************************ |
|
Filter Years |
|
************************************/ |
|
|
|
function findStartAndEndIndex (untils, start, end) { |
|
var startI = 0, |
|
endI = untils.length + 1, |
|
untilYear, |
|
i; |
|
|
|
if (!end) { |
|
end = start; |
|
} |
|
|
|
if (start > end) { |
|
i = start; |
|
start = end; |
|
end = i; |
|
} |
|
|
|
for (i = 0; i < untils.length; i++) { |
|
if (untils[i] == null) { |
|
continue; |
|
} |
|
untilYear = new Date(untils[i]).getUTCFullYear(); |
|
if (untilYear < start) { |
|
startI = i + 1; |
|
} |
|
if (untilYear > end) { |
|
endI = Math.min(endI, i + 1); |
|
} |
|
} |
|
|
|
return [startI, endI]; |
|
} |
|
|
|
function filterYears (source, start, end) { |
|
var slice = Array.prototype.slice, |
|
indices = findStartAndEndIndex(source.untils, start, end), |
|
untils = slice.apply(source.untils, indices); |
|
|
|
untils[untils.length - 1] = null; |
|
|
|
return { |
|
name : source.name, |
|
abbrs : slice.apply(source.abbrs, indices), |
|
untils : untils, |
|
offsets : slice.apply(source.offsets, indices), |
|
population : source.population, |
|
countries : source.countries |
|
}; |
|
} |
|
|
|
/************************************ |
|
Filter, Link, and Pack |
|
************************************/ |
|
|
|
function filterLinkPack (input, start, end, groupLeaders) { |
|
var i, |
|
inputZones = input.zones, |
|
outputZones = [], |
|
output; |
|
|
|
for (i = 0; i < inputZones.length; i++) { |
|
outputZones[i] = filterYears(inputZones[i], start, end); |
|
} |
|
|
|
output = createLinks({ |
|
zones : outputZones, |
|
links : input.links.slice(), |
|
version : input.version |
|
}, groupLeaders); |
|
|
|
for (i = 0; i < output.zones.length; i++) { |
|
output.zones[i] = pack(output.zones[i]); |
|
} |
|
|
|
output.countries = input.countries ? input.countries.map(function (unpacked) { |
|
return packCountry(unpacked); |
|
}) : []; |
|
|
|
return output; |
|
} |
|
|
|
/************************************ |
|
Exports |
|
************************************/ |
|
|
|
moment.tz.pack = pack; |
|
moment.tz.packBase60 = packBase60; |
|
moment.tz.createLinks = createLinks; |
|
moment.tz.filterYears = filterYears; |
|
moment.tz.filterLinkPack = filterLinkPack; |
|
moment.tz.packCountry = packCountry; |
|
|
|
return moment; |
|
}));
|
|
|