hexo/node_modules/moment-timezone/moment-timezone-utils.js

340 lines
7.9 KiB
JavaScript

//! moment-timezone-utils.js
//! version : 0.5.43
//! 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;
}));