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.
		
		
		
		
		
			
		
			
				
					185 lines
				
				5.2 KiB
			
		
		
			
		
	
	
					185 lines
				
				5.2 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								import { MIN, MS } from '../../constant';
							 | 
						||
| 
								 | 
							
								var typeToPos = {
							 | 
						||
| 
								 | 
							
								  year: 0,
							 | 
						||
| 
								 | 
							
								  month: 1,
							 | 
						||
| 
								 | 
							
								  day: 2,
							 | 
						||
| 
								 | 
							
								  hour: 3,
							 | 
						||
| 
								 | 
							
								  minute: 4,
							 | 
						||
| 
								 | 
							
								  second: 5
							 | 
						||
| 
								 | 
							
								}; // Cache time-zone lookups from Intl.DateTimeFormat,
							 | 
						||
| 
								 | 
							
								// as it is a *very* slow method.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var dtfCache = {};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var getDateTimeFormat = function getDateTimeFormat(timezone, options) {
							 | 
						||
| 
								 | 
							
								  if (options === void 0) {
							 | 
						||
| 
								 | 
							
								    options = {};
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var timeZoneName = options.timeZoneName || 'short';
							 | 
						||
| 
								 | 
							
								  var key = timezone + "|" + timeZoneName;
							 | 
						||
| 
								 | 
							
								  var dtf = dtfCache[key];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (!dtf) {
							 | 
						||
| 
								 | 
							
								    dtf = new Intl.DateTimeFormat('en-US', {
							 | 
						||
| 
								 | 
							
								      hour12: false,
							 | 
						||
| 
								 | 
							
								      timeZone: timezone,
							 | 
						||
| 
								 | 
							
								      year: 'numeric',
							 | 
						||
| 
								 | 
							
								      month: '2-digit',
							 | 
						||
| 
								 | 
							
								      day: '2-digit',
							 | 
						||
| 
								 | 
							
								      hour: '2-digit',
							 | 
						||
| 
								 | 
							
								      minute: '2-digit',
							 | 
						||
| 
								 | 
							
								      second: '2-digit',
							 | 
						||
| 
								 | 
							
								      timeZoneName: timeZoneName
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								    dtfCache[key] = dtf;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return dtf;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export default (function (o, c, d) {
							 | 
						||
| 
								 | 
							
								  var defaultTimezone;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var makeFormatParts = function makeFormatParts(timestamp, timezone, options) {
							 | 
						||
| 
								 | 
							
								    if (options === void 0) {
							 | 
						||
| 
								 | 
							
								      options = {};
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    var date = new Date(timestamp);
							 | 
						||
| 
								 | 
							
								    var dtf = getDateTimeFormat(timezone, options);
							 | 
						||
| 
								 | 
							
								    return dtf.formatToParts(date);
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var tzOffset = function tzOffset(timestamp, timezone) {
							 | 
						||
| 
								 | 
							
								    var formatResult = makeFormatParts(timestamp, timezone);
							 | 
						||
| 
								 | 
							
								    var filled = [];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    for (var i = 0; i < formatResult.length; i += 1) {
							 | 
						||
| 
								 | 
							
								      var _formatResult$i = formatResult[i],
							 | 
						||
| 
								 | 
							
								          type = _formatResult$i.type,
							 | 
						||
| 
								 | 
							
								          value = _formatResult$i.value;
							 | 
						||
| 
								 | 
							
								      var pos = typeToPos[type];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      if (pos >= 0) {
							 | 
						||
| 
								 | 
							
								        filled[pos] = parseInt(value, 10);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    var hour = filled[3]; // Workaround for the same behavior in different node version
							 | 
						||
| 
								 | 
							
								    // https://github.com/nodejs/node/issues/33027
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /* istanbul ignore next */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    var fixedHour = hour === 24 ? 0 : hour;
							 | 
						||
| 
								 | 
							
								    var utcString = filled[0] + "-" + filled[1] + "-" + filled[2] + " " + fixedHour + ":" + filled[4] + ":" + filled[5] + ":000";
							 | 
						||
| 
								 | 
							
								    var utcTs = d.utc(utcString).valueOf();
							 | 
						||
| 
								 | 
							
								    var asTS = +timestamp;
							 | 
						||
| 
								 | 
							
								    var over = asTS % 1000;
							 | 
						||
| 
								 | 
							
								    asTS -= over;
							 | 
						||
| 
								 | 
							
								    return (utcTs - asTS) / (60 * 1000);
							 | 
						||
| 
								 | 
							
								  }; // find the right offset a given local time. The o input is our guess, which determines which
							 | 
						||
| 
								 | 
							
								  // offset we'll pick in ambiguous cases (e.g. there are two 3 AMs b/c Fallback DST)
							 | 
						||
| 
								 | 
							
								  // https://github.com/moment/luxon/blob/master/src/datetime.js#L76
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var fixOffset = function fixOffset(localTS, o0, tz) {
							 | 
						||
| 
								 | 
							
								    // Our UTC time is just a guess because our offset is just a guess
							 | 
						||
| 
								 | 
							
								    var utcGuess = localTS - o0 * 60 * 1000; // Test whether the zone matches the offset for this ts
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    var o2 = tzOffset(utcGuess, tz); // If so, offset didn't change and we're done
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (o0 === o2) {
							 | 
						||
| 
								 | 
							
								      return [utcGuess, o0];
							 | 
						||
| 
								 | 
							
								    } // If not, change the ts by the difference in the offset
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    utcGuess -= (o2 - o0) * 60 * 1000; // If that gives us the local time we want, we're done
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    var o3 = tzOffset(utcGuess, tz);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (o2 === o3) {
							 | 
						||
| 
								 | 
							
								      return [utcGuess, o2];
							 | 
						||
| 
								 | 
							
								    } // If it's different, we're in a hole time.
							 | 
						||
| 
								 | 
							
								    // The offset has changed, but the we don't adjust the time
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return [localTS - Math.min(o2, o3) * 60 * 1000, Math.max(o2, o3)];
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var proto = c.prototype;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  proto.tz = function (timezone, keepLocalTime) {
							 | 
						||
| 
								 | 
							
								    if (timezone === void 0) {
							 | 
						||
| 
								 | 
							
								      timezone = defaultTimezone;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    var oldOffset = this.utcOffset();
							 | 
						||
| 
								 | 
							
								    var date = this.toDate();
							 | 
						||
| 
								 | 
							
								    var target = date.toLocaleString('en-US', {
							 | 
						||
| 
								 | 
							
								      timeZone: timezone
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								    var diff = Math.round((date - new Date(target)) / 1000 / 60);
							 | 
						||
| 
								 | 
							
								    var ins = d(target).$set(MS, this.$ms).utcOffset(-Math.round(date.getTimezoneOffset() / 15) * 15 - diff, true);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (keepLocalTime) {
							 | 
						||
| 
								 | 
							
								      var newOffset = ins.utcOffset();
							 | 
						||
| 
								 | 
							
								      ins = ins.add(oldOffset - newOffset, MIN);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    ins.$x.$timezone = timezone;
							 | 
						||
| 
								 | 
							
								    return ins;
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  proto.offsetName = function (type) {
							 | 
						||
| 
								 | 
							
								    // type: short(default) / long
							 | 
						||
| 
								 | 
							
								    var zone = this.$x.$timezone || d.tz.guess();
							 | 
						||
| 
								 | 
							
								    var result = makeFormatParts(this.valueOf(), zone, {
							 | 
						||
| 
								 | 
							
								      timeZoneName: type
							 | 
						||
| 
								 | 
							
								    }).find(function (m) {
							 | 
						||
| 
								 | 
							
								      return m.type.toLowerCase() === 'timezonename';
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								    return result && result.value;
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var oldStartOf = proto.startOf;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  proto.startOf = function (units, startOf) {
							 | 
						||
| 
								 | 
							
								    if (!this.$x || !this.$x.$timezone) {
							 | 
						||
| 
								 | 
							
								      return oldStartOf.call(this, units, startOf);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    var withoutTz = d(this.format('YYYY-MM-DD HH:mm:ss:SSS'));
							 | 
						||
| 
								 | 
							
								    var startOfWithoutTz = oldStartOf.call(withoutTz, units, startOf);
							 | 
						||
| 
								 | 
							
								    return startOfWithoutTz.tz(this.$x.$timezone, true);
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  d.tz = function (input, arg1, arg2) {
							 | 
						||
| 
								 | 
							
								    var parseFormat = arg2 && arg1;
							 | 
						||
| 
								 | 
							
								    var timezone = arg2 || arg1 || defaultTimezone;
							 | 
						||
| 
								 | 
							
								    var previousOffset = tzOffset(+d(), timezone);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (typeof input !== 'string') {
							 | 
						||
| 
								 | 
							
								      // timestamp number || js Date || Day.js
							 | 
						||
| 
								 | 
							
								      return d(input).tz(timezone);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    var localTs = d.utc(input, parseFormat).valueOf();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    var _fixOffset = fixOffset(localTs, previousOffset, timezone),
							 | 
						||
| 
								 | 
							
								        targetTs = _fixOffset[0],
							 | 
						||
| 
								 | 
							
								        targetOffset = _fixOffset[1];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    var ins = d(targetTs).utcOffset(targetOffset);
							 | 
						||
| 
								 | 
							
								    ins.$x.$timezone = timezone;
							 | 
						||
| 
								 | 
							
								    return ins;
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  d.tz.guess = function () {
							 | 
						||
| 
								 | 
							
								    return Intl.DateTimeFormat().resolvedOptions().timeZone;
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  d.tz.setDefault = function (timezone) {
							 | 
						||
| 
								 | 
							
								    defaultTimezone = timezone;
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								});
							 |