diff --git a/README.md b/README.md index fe475db..6f5ff30 100644 --- a/README.md +++ b/README.md @@ -201,6 +201,7 @@ cronstrue.toString("*/5 * * * *", { locale: "es" }); // => Cada 5 minutos - af - Afrikaans (Michael van Niekerk(https://github.com/mvniekerk)) - ar - Arabic ([Mohamed Nehad Shalabi](https://github.com/mohamednehad450)) - be - Belarusian ([Kirill Mikulich](https://github.com/KirillMikulich)) +- bg - Bulgarian ([kamenf](https://github.com/kamenf)) - ca - Catalan ([Francisco Javier Barrena](https://github.com/fjbarrena)) - cs - Czech ([hanbar](https://github.com/hanbar)) - es - Spanish ([Ivan Santos](https://github.com/ivansg)) diff --git a/src/i18n/allLocales.ts b/src/i18n/allLocales.ts index dea2de2..afdcc64 100644 --- a/src/i18n/allLocales.ts +++ b/src/i18n/allLocales.ts @@ -34,3 +34,4 @@ export { th } from "./locales/th"; // Thai export { ar } from './locales/ar'; // Arabic export { vi } from './locales/vi'; // Vietnamese export { my } from './locales/my'; // Malay +export { bg } from './locales/bg'; // Bulgarian diff --git a/src/i18n/locales/bg.ts b/src/i18n/locales/bg.ts new file mode 100644 index 0000000..a6ca169 --- /dev/null +++ b/src/i18n/locales/bg.ts @@ -0,0 +1,183 @@ +// Bulgarian + +import type { Locale } from '../locale'; + +const getPhraseByPlural = (str: string | undefined, words: string[]): string => { + const strAsNumber = str != null ? Number(str) : 0; + return strAsNumber < 2 ? words[0]! : words[1]!; +}; +const getPhraseByDayOfWeek = (str: string | undefined, words: string[]): string => { + const strAsNumber = str != null ? Number(str) : 0; + // weekdays: 0:неделя 1:понеделник 2:вторник 3:сряда 4:четвъртък 5:петък 6:събота + // gender: ж м м ж м м ж + return words[[1, 0, 0, 1, 0, 0, 1][strAsNumber]!]!; +}; +const getNumberEnding = (str: string | undefined, gender: 'м' | 'ж' | 'ср'): string => { + let strAsNumber = str != null ? Number(str) : 1; + strAsNumber = Math.max(Math.min(strAsNumber < 10 || (strAsNumber > 20 && strAsNumber % 10 !== 0) ? strAsNumber % 10 : 3, 3), 1) - 1; + const genderIndex = ['м', 'ж', 'ср'].indexOf(gender); + return ['в', 'р', 'т'][strAsNumber]! + ['и', 'а', 'о'][genderIndex]; +}; + +export class bg implements Locale { + public atX0SecondsPastTheMinuteGt20(): string | null { + return null; + } + public atX0MinutesPastTheHourGt20(): string | null { + return null; + } + public commaMonthX0ThroughMonthX1(): string | null { + return null; + } + public commaYearX0ThroughYearX1(): string | null { + return null; + } + public use24HourTimeFormatByDefault(): boolean { + return true; + } + public everyMinute(): string { + return 'всяка минута'; + } + public everyHour(): string { + return 'всеки час'; + } + public anErrorOccuredWhenGeneratingTheExpressionD(): string { + return 'Възникна грешка при генериране на описанието на израза. Проверете синтаксиса на cron израза.'; + } + public atSpace(): string { + return 'В '; + } + public everyMinuteBetweenX0AndX1(): string { + return 'Всяка минута от %s до %s'; + } + public at(): string { + return 'В'; + } + public spaceAnd(): string { + return ' и'; + } + public everySecond(): string { + return 'всяка секунда'; + } + public everyX0Seconds(s?: string): string { + return 'всеки %s секунди'; + } + public secondsX0ThroughX1PastTheMinute(): string { + return 'секунди от %s до %s'; + } + public atX0SecondsPastTheMinute(s?: string): string { + return `%s-${getNumberEnding(s, 'ж')} секунда`; + } + public everyX0Minutes(s?: string): string { + return 'всеки %s минути'; + } + public minutesX0ThroughX1PastTheHour(): string { + return 'минути от %s до %s'; + } + public atX0MinutesPastTheHour(s?: string): string { + return `%s-${getNumberEnding(s, 'ж')} минутa`; + } + public everyX0Hours(s?: string): string { + return 'всеки %s часа'; + } + public betweenX0AndX1(): string { + return 'от %s до %s'; + } + public atX0(): string { + return 'в %s'; + } + public commaEveryDay(): string { + return ', всеки ден'; + } + public commaEveryX0DaysOfTheWeek(s?: string): string { + return getPhraseByPlural(s, [', всеки %s ден от седмицата', ', всеки %s дена от седмицата']); + } + public commaX0ThroughX1(s?: string): string { + return ', от %s до %s'; + } + public commaAndX0ThroughX1(s?: string): string { + return ' и от %s до %s'; + } + public first(s?: string): string { + return getPhraseByDayOfWeek(s, ['первият', 'первата']); + } + public second(s?: string): string { + return getPhraseByDayOfWeek(s, ['вторият', 'втората']); + } + public third(s?: string): string { + return getPhraseByDayOfWeek(s, ['третият', 'третата']); + } + public fourth(s?: string): string { + return getPhraseByDayOfWeek(s, ['четвертият', 'четвертата']); + } + public fifth(s?: string): string { + return getPhraseByDayOfWeek(s, ['петият', 'петата']); + } + public commaOnThe(s?: string): string { + return ', '; + } + public spaceX0OfTheMonth(): string { + return ' %s на месеца'; + } + public lastDay(): string { + return 'последният ден'; + } + public commaOnTheLastX0OfTheMonth(s?: string): string { + return getPhraseByDayOfWeek(s, [', в последният %s от месеца', ', в последната %s отмесеца']); + } + public commaOnlyOnX0(s?: string): string { + return ', %s'; + } + public commaAndOnX0(): string { + return ' и %s'; + } + public commaEveryX0Months(s?: string): string { + return ' всеки %s месеца'; + } + public commaOnlyInMonthX0(): string { + return ', %s'; + } + public commaOnlyInX0(): string { + return ', в %s'; + } + public commaOnTheLastDayOfTheMonth(): string { + return ', в последният ден на месеца'; + } + public commaOnTheLastWeekdayOfTheMonth(): string { + return ', в последния делничен ден от месеца'; + } + public commaDaysBeforeTheLastDayOfTheMonth(s?: string): string { + return getPhraseByPlural(s, [', %s ден преди края на месеца', ', %s дена преди края на месеца']); + } + public firstWeekday(): string { + return 'първият делничен ден'; + } + public weekdayNearestDayX0(): string { + return 'най-близкият делничен ден до %s число'; + } + public commaOnTheX0OfTheMonth(): string { + return ', на %s число от месеца'; + } + public commaEveryX0Days(s?: string): string { + return getPhraseByPlural(s, [', всеки %s ден', ', всеки %s дена']); + } + public commaBetweenDayX0AndX1OfTheMonth(s?: string): string { + const values = s?.split('-') ?? []; + return `, от %s-${getNumberEnding(values[0], 'ср')} до %s-${getNumberEnding(values[1], 'ср')} число на месеца`; + } + public commaOnDayX0OfTheMonth(s?: string): string { + return `, на %s-${getNumberEnding(s, 'ср')} число от месеца`; + } + public commaEveryX0Years(s?: string): string { + return getPhraseByPlural(s, [', всяка %s година', ', всеки %s години']); + } + public commaStartingX0(): string { + return ', започвайки %s'; + } + public daysOfTheWeek(): string[] { + return ['неделя', 'понеделник', 'вторник', 'сряда', 'четвъртък', 'петък', 'събота']; + } + public monthsOfTheYear(): string[] { + return ['януари', 'февруари', 'март', 'април', 'май', 'юни', 'юли', 'август', 'септевмври', 'октомври', 'ноември', 'декември']; + } +} diff --git a/test/i18n.ts b/test/i18n.ts index 8d1b1fd..f0edebc 100644 --- a/test/i18n.ts +++ b/test/i18n.ts @@ -392,4 +392,15 @@ describe("i18n", function () { }); }); + describe("bg", function () { + it("* * * * *", function () { + assert.equal(cronstrue.toString(this.test?.title as string, { locale: "bg" }), "Всяка минута"); + }); + it("0 * * * *", function () { + assert.equal(cronstrue.toString(this.test?.title as string, { locale: "bg" }), "Всеки час"); + }); + it("*/5 15 * * MON-FRI", function () { + assert.equal(cronstrue.toString(this.test?.title as string, { locale: "bg" }), "Всеки 5 минути, от 15:00 до 15:59, от понеделник до петък"); + }); + }); });