: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
/************************************
************************************/
function Zone (packedString) {
this._set(unpack(packedString));
_set : function (unpacked) {
this.name = unpacked.name;
this.abbrs = unpacked.abbrs;
this.untils = unpacked.untils;
this.offsets = unpacked.offsets;
this.population = unpacked.population;
_index : function (timestamp) {
for (i = 0; i < untils.length; i++) {
if (target < untils[i]) {
countries : function () {
var zone_name = this.name;
return Object.keys(countries).filter(function (country_code) {
return countries[country_code].zones.indexOf(zone_name) !== -1;
parse : function (timestamp) {
offset, offsetNext, offsetPrev, i;
for (i = 0; i < max; i++) {
offsetNext = offsets[i + 1];
offsetPrev = offsets[i ? i - 1 : i];
if (offset < offsetNext && tz.moveAmbiguousForward) {
} else if (offset > offsetPrev && tz.moveInvalidForward) {
if (target < untils[i] - (offset * 60000)) {
return this.abbrs[this._index(mom)];
offset : function (mom) {
logError("zone.offset has been deprecated in favor of zone.utcOffset");
return this.offsets[this._index(mom)];
utcOffset : function (mom) {
return this.offsets[this._index(mom)];
/************************************
************************************/
function Country (country_name, zone_names) {
this.name = country_name;
/************************************
************************************/
var timeString = at.toTimeString();
var abbr = timeString.match(/\([a-z ]+\)/i);
// 17:56:31 GMT-0600 (CST)
// 17:56:31 GMT-0600 (Central Standard Time)
abbr = abbr[0].match(/[A-Z]/g);
abbr = abbr ? abbr.join('') : undefined;
// 17:56:31 GMT+0800 (台北標準時間)
abbr = timeString.match(/[A-Z]{3,5}/g);
abbr = abbr ? abbr[0] : undefined;
this.offset = at.getTimezoneOffset();
function ZoneScore(zone) {
ZoneScore.prototype.scoreOffsetAt = function (offsetAt) {
this.offsetScore += Math.abs(this.zone.utcOffset(offsetAt.at) - offsetAt.offset);
if (this.zone.abbr(offsetAt.at).replace(/[^A-Z]/g, '') !== offsetAt.abbr) {
function findChange(low, high) {
while ((diff = ((high.at - low.at) / 12e4 | 0) * 6e4)) {
mid = new OffsetAt(new Date(low.at + diff));
if (mid.offset === low.offset) {
var startYear = new Date().getFullYear() - 2,
last = new OffsetAt(new Date(startYear, 0, 1)),
for (i = 1; i < 48; i++) {
next = new OffsetAt(new Date(startYear, i, 1));
if (next.offset !== last.offset) {
change = findChange(last, next);
offsets.push(new OffsetAt(new Date(change.at + 6e4)));
for (i = 0; i < 4; i++) {
offsets.push(new OffsetAt(new Date(startYear + i, 0, 1)));
offsets.push(new OffsetAt(new Date(startYear + i, 6, 1)));
function sortZoneScores (a, b) {
if (a.offsetScore !== b.offsetScore) {
return a.offsetScore - b.offsetScore;
if (a.abbrScore !== b.abbrScore) {
return a.abbrScore - b.abbrScore;
if (a.zone.population !== b.zone.population) {
return b.zone.population - a.zone.population;
return b.zone.name.localeCompare(a.zone.name);
function addToGuesses (name, offsets) {
for (i = 0; i < offsets.length; i++) {
guesses[offset] = guesses[offset] || {};
guesses[offset][name] = true;
function guessesForUserOffsets (offsets) {
var offsetsLength = offsets.length,
for (i = 0; i < offsetsLength; i++) {
guessesOffset = guesses[offsets[i].offset] || {};
for (j in guessesOffset) {
if (guessesOffset.hasOwnProperty(j)) {
filteredGuesses[j] = true;
for (i in filteredGuesses) {
if (filteredGuesses.hasOwnProperty(i)) {
function rebuildGuess () {
// use Intl API when available and returning valid time zone
var intlName = Intl.DateTimeFormat().resolvedOptions().timeZone;
if (intlName && intlName.length > 3) {
var name = names[normalizeName(intlName)];
logError("Moment Timezone found " + intlName + " from the Intl api, but did not have that data loaded.");
// Intl unavailable, fall back to manual guessing.
var offsets = userOffsets(),
offsetsLength = offsets.length,
guesses = guessesForUserOffsets(offsets),
for (i = 0; i < guesses.length; i++) {
zoneScore = new ZoneScore(getZone(guesses[i]), offsetsLength);
for (j = 0; j < offsetsLength; j++) {
zoneScore.scoreOffsetAt(offsets[j]);
zoneScores.push(zoneScore);
zoneScores.sort(sortZoneScores);
return zoneScores.length > 0 ? zoneScores[0].zone.name : undefined;
function guess (ignoreCache) {
if (!cachedGuess || ignoreCache) {
cachedGuess = rebuildGuess();
/************************************
************************************/
function normalizeName (name) {
return (name || '').toLowerCase().replace(/\//g, '_');
function addZone (packed) {
var i, name, split, normalized;
if (typeof packed === "string") {
for (i = 0; i < packed.length; i++) {
split = packed[i].split('|');
normalized = normalizeName(name);
zones[normalized] = packed[i];
names[normalized] = name;
addToGuesses(normalized, split[2].split(' '));
function getZone (name, caller) {
name = normalizeName(name);
if (zone instanceof Zone) {
if (typeof zone === 'string') {
// Pass getZone to prevent recursion more than 1 level deep
if (links[name] && caller !== getZone && (link = getZone(links[name], getZone))) {
zone = zones[name] = new Zone();
if (names.hasOwnProperty(i) && (zones[i] || zones[links[i]]) && names[i]) {
function getCountryNames () {
return Object.keys(countries);
function addLink (aliases) {
var i, alias, normal0, normal1;
if (typeof aliases === "string") {
for (i = 0; i < aliases.length; i++) {
alias = aliases[i].split('|');
normal0 = normalizeName(alias[0]);
normal1 = normalizeName(alias[1]);
links[normal0] = normal1;
names[normal0] = alias[0];
links[normal1] = normal0;
names[normal1] = alias[1];
function addCountries (data) {
var i, country_code, country_zones, split;
if (!data || !data.length) return;
for (i = 0; i < data.length; i++) {
split = data[i].split('|');
country_code = split[0].toUpperCase();
country_zones = split[1].split(' ');
countries[country_code] = new Country(
function getCountry (name) {
name = name.toUpperCase();
return countries[name] || null;
function zonesForCountry(country, with_offset) {
country = getCountry(country);
if (!country) return null;
var zones = country.zones.sort();
return zones.map(function (zone_name) {
var zone = getZone(zone_name);
offset: zone.utcOffset(new Date())
function loadData (data) {
addCountries(data.countries);
tz.dataVersion = data.version;
function zoneExists (name) {
if (!zoneExists.didShowError) {
zoneExists.didShowError = true;
logError("moment.tz.zoneExists('" + name + "') has been deprecated in favor of !moment.tz.zone('" + name + "')");
function needsOffset (m) {
var isUnixTimestamp = (m._f === 'X' || m._f === 'x');
return !!(m._a && (m._tzm === undefined) && !isUnixTimestamp);
function logError (message) {
if (typeof console !== 'undefined' && typeof console.error === 'function') {
/************************************
************************************/
var args = Array.prototype.slice.call(arguments, 0, -1),
name = arguments[arguments.length - 1],
out = moment.utc.apply(null, args);
if (zone && !moment.isMoment(input) && needsOffset(out)) {
out.add(zone.parse(out), 'minutes');
tz._countries = countries;
tz.zoneExists = zoneExists; // deprecated in 0.1.0
tz.unpackBase60 = unpackBase60;
tz.needsOffset = needsOffset;
tz.moveInvalidForward = true;
tz.moveAmbiguousForward = false;
tz.countries = getCountryNames;
tz.zonesForCountry = zonesForCountry;
/************************************
************************************/
moment.defaultZone = null;
moment.updateOffset = function (mom, keepTime) {
var zone = moment.defaultZone,
if (mom._z === undefined) {
if (zone && needsOffset(mom) && !mom._isUTC) {
mom._d = moment.utc(mom._a)._d;
mom.utc().add(zone.parse(mom), 'minutes');
offset = mom._z.utcOffset(mom);
if (Math.abs(offset) < 16) {
if (mom.utcOffset !== undefined) {
mom.utcOffset(-offset, keepTime);
mom.zone(offset, keepTime);
fn.tz = function (name, keepTime) {
if (typeof name !== 'string') {
throw new Error('Time zone name must be a string, got ' + name + ' [' + typeof name + ']');