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.
		
		
		
		
		
			
		
			
				
					
					
						
							340 lines
						
					
					
						
							7.6 KiB
						
					
					
				
			
		
		
	
	
							340 lines
						
					
					
						
							7.6 KiB
						
					
					
				| //! 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;
 | |
| }));
 |