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
			| 
											3 years ago
										 | //! 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; | ||
|  | })); |