diff --git a/moment-timezone.js b/moment-timezone.js index e27c4de6..a05d95b0 100644 --- a/moment-timezone.js +++ b/moment-timezone.js @@ -330,7 +330,7 @@ // use Intl API when available and returning valid time zone try { var intlName = Intl.DateTimeFormat().resolvedOptions().timeZone; - if (intlName){ + if (isIntlNameCredible(intlName)){ var name = names[normalizeName(intlName)]; if (name) { return name; @@ -360,6 +360,27 @@ return zoneScores.length > 0 ? zoneScores[0].zone.name : undefined; } + // for issue: https://github.com/moment/moment-timezone/issues/517 + function isIntlNameCredible (intlName) { + if (!intlName) { + return false; + } + + var zone = getZone(intlName), + browserOffset = new Date().getTimezoneOffset(), + i, + validOffset; + if (zone) { + for (i = 0; i < zone.offsets.length && !validOffset; i++) { + if (zone.offsets[i].offset === browserOffset) { + validOffset = zone.offsets[i].offset; + } + } + } + + return !!validOffset; + } + function guess (ignoreCache) { if (!cachedGuess || ignoreCache) { cachedGuess = rebuildGuess(); diff --git a/tests/moment-timezone/guess.js b/tests/moment-timezone/guess.js index 7bc02761..4a6a0b19 100644 --- a/tests/moment-timezone/guess.js +++ b/tests/moment-timezone/guess.js @@ -77,9 +77,11 @@ exports.guess = { "When Intl is available, it is used" : function (test) { mockIntlTimeZone('Europe/London'); + mockTimezoneOffset(tz.zone('Europe/London')); test.equal(tz.guess(true), 'Europe/London'); mockIntlTimeZone('America/New_York'); + mockTimezoneOffset(tz.zone('America/New_York')); test.equal(tz.guess(true), 'America/New_York'); mockIntlTimeZone('America/Some_Missing_Zone'); @@ -95,7 +97,7 @@ exports.guess = { console.error = function (message) { errors += message; }; - + mockIntlTimeZone(undefined); mockTimezoneOffset(tz.zone('Europe/London')); test.equal(tz.guess(true), 'Europe/London'); @@ -115,5 +117,17 @@ exports.guess = { test.ok(tz.guess(true), "Should have a guess for " + zone.name + ")"); } test.done(); + }, + + "check Intl.DateTimeFormat().resolvedOptions().timeZone is credible" : function (test) { + mockTimezoneOffset(tz.zone('Asia/Shanghai')) + mockIntlTimeZone('America/Chicago') + var guessedName = tz.guess(true) + test.equal( + tz.zone(guessedName).offset(Date.now()), + tz.zone('Asia/Shanghai').offset(Date.now()), + "Should have a guess for Asia/Shanghai)", + ); + test.done(); } };