From 5470a15e437fac803797363063b24f3ba3bd5299 Mon Sep 17 00:00:00 2001 From: alesf Date: Tue, 19 Sep 2023 13:41:20 +0200 Subject: [PATCH] fix: Update Slovenian locale for relative time (#2396) Slovenian translation update so it handles dual and some plural edge cases. --- src/locale/sl.js | 91 ++++++++++++++++++++++++++++++++++++------ test/locale/sl.test.js | 82 +++++++++++++++++++++++++++++++++++++ 2 files changed, 160 insertions(+), 13 deletions(-) create mode 100644 test/locale/sl.test.js diff --git a/src/locale/sl.js b/src/locale/sl.js index f09e3bfce..1e0e4f885 100644 --- a/src/locale/sl.js +++ b/src/locale/sl.js @@ -1,6 +1,71 @@ // Slovenian [sl] import dayjs from 'dayjs' +function dual(n) { + return (n % 100) == 2 // eslint-disable-line +} + +function threeFour(n) { + return (n % 100) == 3 || (n % 100) == 4 // eslint-disable-line +} + +/* eslint-disable */ +function translate(number, withoutSuffix, key, isFuture) { + const result = `${number} ` + switch (key) { + case 's': // a few seconds / in a few seconds / a few seconds ago + return (withoutSuffix || isFuture) ? 'nekaj sekund' : 'nekaj sekundami' + case 'm': // a minute / in a minute / a minute ago + return withoutSuffix ? 'ena minuta' : 'eno minuto' + case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago + if (dual(number)) { + return result + ((withoutSuffix || isFuture) ? 'minuti' : 'minutama') + } + if (threeFour(number)) { + return result + ((withoutSuffix || isFuture) ? 'minute' : 'minutami') + } + return result + ((withoutSuffix || isFuture) ? 'minut' : 'minutami') + case 'h': // an hour / in an hour / an hour ago + return withoutSuffix ? 'ena ura' : (isFuture ? 'eno uro' : 'eno uro') + case 'hh': // 9 hours / in 9 hours / 9 hours ago + if (dual(number)) { + return result + ((withoutSuffix || isFuture) ? 'uri' : 'urama') + } + if (threeFour(number)) { + return result + ((withoutSuffix || isFuture) ? 'ure' : 'urami') + } + return result + ((withoutSuffix || isFuture) ? 'ur' : 'urami') + case 'd': // a day / in a day / a day ago + return (withoutSuffix || isFuture) ? 'en dan' : 'enim dnem' + case 'dd': // 9 days / in 9 days / 9 days ago + if (dual(number)) { + return result + ((withoutSuffix || isFuture) ? 'dneva' : 'dnevoma') + } + return result + ((withoutSuffix || isFuture) ? 'dni' : 'dnevi') + case 'M': // a month / in a month / a month ago + return (withoutSuffix || isFuture) ? 'en mesec' : 'enim mesecem' + case 'MM': // 9 months / in 9 months / 9 months ago + if (dual(number)) { // 2 minutes / in 2 minutes + return result + ((withoutSuffix || isFuture) ? 'meseca' : 'mesecema') + } + if (threeFour(number)) { + return result + ((withoutSuffix || isFuture) ? 'mesece' : 'meseci') + } + return result + ((withoutSuffix || isFuture) ? 'mesecev' : 'meseci') + case 'y': // a year / in a year / a year ago + return (withoutSuffix || isFuture) ? 'eno leto' : 'enim letom' + case 'yy': // 9 years / in 9 years / 9 years ago + if (dual(number)) { // 2 minutes / in 2 minutes + return result + ((withoutSuffix || isFuture) ? 'leti' : 'letoma') + } + if (threeFour(number)) { + return result + ((withoutSuffix || isFuture) ? 'leta' : 'leti') + } + return result + ((withoutSuffix || isFuture) ? 'let' : 'leti') + } +} + +/* eslint-enable */ const locale = { name: 'sl', weekdays: 'nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota'.split('_'), @@ -16,26 +81,26 @@ const locale = { L: 'DD.MM.YYYY', LL: 'D. MMMM YYYY', LLL: 'D. MMMM YYYY H:mm', - LLLL: 'dddd, D. MMMM YYYY H:mm' + LLLL: 'dddd, D. MMMM YYYY H:mm', + l: 'D. M. YYYY' }, relativeTime: { future: 'čez %s', past: 'pred %s', - s: 'nekaj sekund', - m: 'minuta', - mm: '%d minut', - h: 'ura', - hh: '%d ur', - d: 'dan', - dd: '%d dni', - M: 'mesec', - MM: '%d mesecev', - y: 'leto', - yy: '%d let' + s: translate, + m: translate, + mm: translate, + h: translate, + hh: translate, + d: translate, + dd: translate, + M: translate, + MM: translate, + y: translate, + yy: translate } } dayjs.locale(locale, null, true) export default locale - diff --git a/test/locale/sl.test.js b/test/locale/sl.test.js new file mode 100644 index 000000000..672d6064b --- /dev/null +++ b/test/locale/sl.test.js @@ -0,0 +1,82 @@ +import MockDate from 'mockdate' +import dayjs from '../../src' +import relativeTime from '../../src/plugin/relativeTime' +import '../../src/locale/sl' + +dayjs.extend(relativeTime) + +beforeEach(() => { + MockDate.set(new Date()) +}) + +afterEach(() => { + MockDate.reset() +}) + +it('Slovenian locale relative time in past and future', () => { + const cases = [ + [1, 's', 'čez nekaj sekund', 'nekaj sekund'], + [-1, 's', 'pred nekaj sekundami', 'nekaj sekund'], + [1, 'm', 'čez eno minuto', 'ena minuta'], + [-1, 'm', 'pred eno minuto', 'ena minuta'], + [2, 'm', 'čez 2 minuti', '2 minuti'], + [-2, 'm', 'pred 2 minutama', '2 minuti'], + [3, 'm', 'čez 3 minute', '3 minute'], + [-3, 'm', 'pred 3 minutami', '3 minute'], + [5, 'm', 'čez 5 minut', '5 minut'], + [-5, 'm', 'pred 5 minutami', '5 minut'], + [1, 'h', 'čez eno uro', 'ena ura'], + [-1, 'h', 'pred eno uro', 'ena ura'], + [2, 'h', 'čez 2 uri', '2 uri'], + [-2, 'h', 'pred 2 urama', '2 uri'], + [3, 'h', 'čez 3 ure', '3 ure'], + [-3, 'h', 'pred 3 urami', '3 ure'], + [5, 'h', 'čez 5 ur', '5 ur'], + [-5, 'h', 'pred 5 urami', '5 ur'], + [1, 'd', 'čez en dan', 'en dan'], + [-1, 'd', 'pred enim dnem', 'en dan'], + [2, 'd', 'čez 2 dneva', '2 dneva'], + [-2, 'd', 'pred 2 dnevoma', '2 dneva'], + [3, 'd', 'čez 3 dni', '3 dni'], + [-3, 'd', 'pred 3 dnevi', '3 dni'], + [5, 'd', 'čez 5 dni', '5 dni'], + [-5, 'd', 'pred 5 dnevi', '5 dni'], + [1, 'M', 'čez en mesec', 'en mesec'], + [-1, 'M', 'pred enim mesecem', 'en mesec'], + [2, 'M', 'čez 2 meseca', '2 meseca'], + [-2, 'M', 'pred 2 mesecema', '2 meseca'], + [3, 'M', 'čez 3 mesece', '3 mesece'], + [-3, 'M', 'pred 3 meseci', '3 mesece'], + [5, 'M', 'čez 5 mesecev', '5 mesecev'], + [-5, 'M', 'pred 5 meseci', '5 mesecev'], + [1, 'y', 'čez eno leto', 'eno leto'], + [-1, 'y', 'pred enim letom', 'eno leto'], + [2, 'y', 'čez 2 leti', '2 leti'], + [-2, 'y', 'pred 2 letoma', '2 leti'], + [3, 'y', 'čez 3 leta', '3 leta'], + [-3, 'y', 'pred 3 leti', '3 leta'], + [5, 'y', 'čez 5 let', '5 let'], + [-5, 'y', 'pred 5 leti', '5 let'] + // these are rounded + // if user decides to change rounding then it would be good to test them also + // [102, 's', 'čez 102 sekundi', '102 sekundi'], + // [-102, 's', 'pred 102 sekundama', '102 sekundi'], + // [103, 's', 'čez 103 sekunde', '103 sekunde'], + // [-103, 's', 'pred 103 sekundami', '103 sekunde'], + // [114, 's', 'čez 114 sekund', '114 sekund'], + // [-114, 's', 'pred 114 sekundami', '114 sekund'], + // [-102, 'm', 'čez 102 minuti', '102 minuti'], + // [-102, 'm', 'pred 102 minutama', '102 minuti'], + // [103, 'm', 'čez 103 minute', '103 minute'], + // [-103, 'm', 'pred 103 minutami', '103 minute'], + // [114, 'm', 'čez 114 minut', '114 minut'], + // [-114, 'm', 'pred 114 minutami', '114 minut'] + ] + + cases.forEach((c) => { + // With suffix + expect(dayjs().add(c[0], c[1]).locale('sl').fromNow()).toBe(c[2]) + // Without suffix + expect(dayjs().add(c[0], c[1]).locale('sl').fromNow(true)).toBe(c[3]) + }) +})