diff --git a/src/impl/locale.js b/src/impl/locale.js index 93c489b0..093859aa 100644 --- a/src/impl/locale.js +++ b/src/impl/locale.js @@ -1,4 +1,11 @@ -import { hasLocaleWeekInfo, hasRelative, padStart, roundTo, validateWeekSettings } from "./util.js"; +import { + hasList, + hasLocaleWeekInfo, + hasRelative, + padStart, + roundTo, + validateWeekSettings, +} from "./util.js"; import * as English from "./english.js"; import Settings from "../settings.js"; import DateTime from "../datetime.js"; @@ -317,6 +324,26 @@ class PolyRelFormatter { } } +/** + * @private + */ +class PolyListFormatter { + constructor(intl, opts) { + this.opts = opts; + if (hasList()) { + this.lf = getCachedLF(intl, opts); + } + } + + format(list) { + if (this.lf) { + return this.lf.format(list); + } else { + return list.join(", "); + } + } +} + const fallbackWeekSettings = { firstDay: 1, minimalDays: 4, @@ -499,7 +526,7 @@ export default class Locale { } listFormatter(opts = {}) { - return getCachedLF(this.intl, opts); + return new PolyListFormatter(this.intl, opts); } isEnglish() { diff --git a/src/impl/util.js b/src/impl/util.js index a9b548c3..4d8a7d31 100644 --- a/src/impl/util.js +++ b/src/impl/util.js @@ -44,6 +44,14 @@ export function hasRelative() { } } +export function hasList() { + try { + return typeof Intl !== "undefined" && !!Intl.ListFormat; + } catch (e) { + return false; + } +} + export function hasLocaleWeekInfo() { try { return ( diff --git a/test/duration/format.test.js b/test/duration/format.test.js index 408660f8..b0a6a910 100644 --- a/test/duration/format.test.js +++ b/test/duration/format.test.js @@ -1,6 +1,8 @@ /* global test expect */ import { Duration } from "../../src/luxon"; +const Helpers = require("../helpers"); + const dur = () => Duration.fromObject({ years: 1, @@ -314,3 +316,15 @@ test("Duration#toHuman works in differt languages", () => { "1 an, 2 mois, 1 semaine, 3 jours, 4 heures, 5 minutes, 6 secondes, 7 millisecondes" ); }); + +Helpers.withoutLF("Duration#toHuman works without LF", () => { + expect(dur().toHuman()).toEqual( + "1 year, 2 months, 1 week, 3 days, 4 hours, 5 minutes, 6 seconds, 7 milliseconds" + ); +}); + +Helpers.withoutLF("Duration#toHuman falls back to commas", () => { + expect(dur().reconfigure({ locale: "ja" }).toHuman()).toEqual( + "1 年, 2 か月, 1 週間, 3 日, 4 時間, 5 分, 6 秒, 7 ミリ秒" + ); +}); diff --git a/test/helpers.js b/test/helpers.js index b3258e94..1dd091de 100644 --- a/test/helpers.js +++ b/test/helpers.js @@ -15,6 +15,20 @@ exports.withoutRTF = function (name, f) { }); }; +exports.withoutLF = function (name, f) { + const fullName = `With no ListFormat support, ${name}`; + test(fullName, () => { + const lf = Intl.ListFormat; + try { + Intl.ListFormat = undefined; + Settings.resetCaches(); + f(); + } finally { + Intl.ListFormat = lf; + } + }); +}; + exports.withoutLocaleWeekInfo = function (name, f) { const fullName = `With no Intl.Locale.weekInfo support, ${name}`; test(fullName, () => {