diff --git a/src/locale/la.js b/src/locale/la.js index 9dca1ecb8..bcc4c6763 100644 --- a/src/locale/la.js +++ b/src/locale/la.js @@ -1,9 +1,25 @@ // Latin [la] import dayjs from 'dayjs' +const monthFormat = 'ianuarii_februarii_martii_aprilis_maii_iunii_iulii_augusti_septembris_octobris_novembris_decembris'.split('_') +const monthStandalone = 'ianuarius_februarius_martius_aprilis_maius_iunius_iulius_augustus_september_october_november_december'.split('_') +const MONTHS_IN_FORMAT = /(D|[CDILMVX]+)[oD.ᵒ]?(\[[^[\]]*\]|\s)+MMMM?/ +const months = (dayjsInstance, format) => { + if (MONTHS_IN_FORMAT.test(format)) { + return monthFormat[dayjsInstance.month()] + } + return monthStandalone[dayjsInstance.month()] +} +months.s = monthStandalone +months.f = monthFormat + /* eslint-disable */ // src: https://stackoverflow.com/a/9083076 +// function romanise(num) { function romanise(num) { + if (isNaN(num)) { + return NaN + } const key = [ '', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM', '', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC', @@ -12,54 +28,23 @@ function romanise(num) { const digits = String(+num).split('') let roman = '' let i = 3 - if (isNaN(num)) { - return NaN - } while (i--) { roman = (key[+digits.pop() + (i * 10)] || '') + roman } return Array(+digits.join('') + 1).join('M') + roman } -function getMonthInGenitive(month) { - switch (month) { - case 'ianuarius': - return 'ianuarii' - case 'februarius': - return 'februarii' - case 'martius': - return 'martii' - case 'aprilis': - return 'aprilis' - case 'maius': - return 'maii' - case 'iunius': - return 'iunii' - case 'iulius': - return 'iulii' - case 'augustus': - return 'augusti' - case 'september': - return 'septembris' - case 'october': - return 'octobris' - case 'november': - return 'novembris' - case 'december': - return 'decembris' - } -} /* eslint-enable */ const locale = { name: 'la', weekdays: 'Dominica_feria secunda_feria tertia_feria quarta_feria quinta_feria sexta_Sabbato'.split('_'), weekdaysShort: 'Dominica_feria II_feria III_feria IV_feria V_feria VI_Sabbato'.split('_'), weekdaysMin: 'Dom._II_III_IV_V_VI_Sab.'.split('_'), - months: 'ianuarius_februarius_martius_aprilis_maius_iunius_iulius_augustus_september_october_november_december'.split('_'), - monthsShort: 'ian_feb_mar_apr_mai_iun_iul_aug_sep_oct_nov_dec'.split('_'), + months, + monthsShort: 'ian._feb._mar._apr._mai._iun._iul._aug._sep._oct._nov._dec'.split('_'), weekStart: 0, yearStart: 4, ordinal: n => [romanise(n), 'ᵒ'].join(''), - // The relative time variables are in Nominative case only + // The relative time variables are in nominative case only relativeTime: { future: 'ad %s', past: 'abhinc %s', @@ -78,10 +63,10 @@ const locale = { formats: { LT: 'HH:mm', LTS: 'HH:mm:ss', - L: ['D. MM. ', romanise('YYYY')].join(''), - LL: ['D. ', getMonthInGenitive('MMMM'), ' ', romanise('YYYY')].join(''), - LLL: ['D. ', getMonthInGenitive('MMMM'), ' ', romanise('YYYY'), ' HH:mm'].join(''), - LLLL: ['dddd, ', 'D. ', getMonthInGenitive('MMMM'), ' ', romanise('YYYY'), ' HH:mm'].join('') + L: 'D. MM. YYYY', + LL: 'D MMMM YYYY', + LLL: 'D MMMM YYYY, HH:mm', + LLLL: 'dddd, D MMMM YYYY, HH:mm' } } diff --git a/test/locale/la.test.js b/test/locale/la.test.js new file mode 100644 index 000000000..c24f5794c --- /dev/null +++ b/test/locale/la.test.js @@ -0,0 +1,90 @@ +import MockDate from 'mockdate' +import dayjs from '../../src' +import advancedFormat from '../../src/plugin/advancedFormat' +import localizedFormat from '../../src/plugin/localizedFormat' +import relativeTime from '../../src/plugin/relativeTime' +import '../../src/locale/la' + +dayjs.extend(advancedFormat) +dayjs.extend(localizedFormat) +dayjs.extend(relativeTime) +dayjs.locale('la') + +beforeEach(() => { + MockDate.set(new Date()) +}) + +afterEach(() => { + MockDate.reset() +}) + +describe('Latin: Output month name:', () => { + const M = [ + [1, 'ianuarius', 'ianuarii'], + [2, 'februarius', 'februarii'], + [3, 'martius', 'martii'], + [4, 'aprilis', 'aprilis'], + [5, 'maius', 'maii'], + [6, 'iunius', 'iunii'], + [7, 'iulius', 'iulii'], + [8, 'augustus', 'augusti'], + [9, 'september', 'septembris'], + [10, 'october', 'octobris'], + [11, 'november', 'novembris'], + [12, 'december', 'decembris'] + ] + + it('in genitive case if day of month is output', () => { + M.forEach((m) => { + const dayjsDay = dayjs(['2020-', m[0], '-01'].join('')).locale('la').format('D MMMM') + const expected = ['1 ', m[2]].join('') + expect(dayjsDay).toBe(expected) + }) + }) + + it('otherwise output it in nominative', () => { + M.forEach((m) => { + const dayjsDay = dayjs(['2020-', m[0], '-01'].join('')).locale('la').format('MMMM') + const expected = m[1] + expect(dayjsDay).toBe(expected) + }) + }) +}) + +it('Latin: Test relative time', () => { + const T = [ + [44.4, 'second', 'paucæ secundæ'], // a few seconds + [89.5, 'second', 'minuta'], // a minute + [2, 'minute', '2 minutæ'], // 2 minutes + [43, 'minute', '43 minutæ'], // 43 minutes + [45, 'minute', 'hora'], // an hour + [3, 'hour', '3 horæ'], // 3 hours + [21, 'hour', '21 horæ'], // 21 hours + [1, 'day', 'dies'], // a day + [3, 'day', '3 dies'], // 3 day + [25, 'day', '25 dies'], // 25 days + [1, 'month', 'mensis'], // a month + [2, 'month', '2 menses'], // 2 month + [10, 'month', '10 menses'], // 10 month + [1, 'year', 'annus'], // a year + [2, 'year', '2 anni'], // 2 year + [5, 'year', '5 anni'], // 5 year + [18, 'month', '2 anni'] // 2 years + ] + + T.forEach((t) => { + dayjs.locale('la') + const dayjsDay = dayjs() + const dayjsCompare = dayjs().add(t[0], t[1]) + const expectedFrom = ['abhinc ', t[2]].join('') + const expectedTo = ['ad ', t[2]].join('') + const expectedFromTrue = t[2] + + expect(dayjsDay.from(dayjsCompare)).toBe(expectedFrom) + expect(dayjsDay.to(dayjsCompare)).toBe(expectedTo) + expect(dayjsDay.from(dayjsCompare, true)).toBe(expectedFromTrue) + }) +}) + +// TODO: Test formats +// TODO: Test romanisation of year (both standalone and in dates incl L, LL, LLL, LLL)