Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation for i18n of toText #13

Open
Prinzhorn opened this issue Apr 17, 2013 · 27 comments
Open

Documentation for i18n of toText #13

Prinzhorn opened this issue Apr 17, 2013 · 27 comments

Comments

@Prinzhorn
Copy link
Contributor

Please add better documentation about i18n of the toText() method.

  1. What's the meaning of the today parameter?
  2. Which values are passed to gettext?
  3. How do I actually translate stuff? I'm able to change dayNames and monthNames, but that's only part of it.

Thank you for creating this lib!

@jkbrzt
Copy link
Owner

jkbrzt commented Apr 17, 2013

What's the meaning of the today parameter?

It's not actually used as of now, you can just pass null.

Which values are passed to gettext?
How do I actually translate stuff? I'm able to change dayNames and monthNames, but that's only part of it.

The API isn't very nice.

You need to create a language definition with date related stuff. The default English one is here. tokens are only needed for RRule.fromText.

gettext gets the English string (you can see what strings are used here).

A crude example (you need the current master, older versions cached the output of toText):

// Date-related translations
var portuguese = {
    dayNames: [
        "Domingo",
        "Segunda-Feira",
        "Terça-feira",
        "Quarta-feira",
        "Quinta-feira",
        "Sexta-feira",
        "Sábado"
    ],
    monthNames: [
        "Janeiro",
        "Fevereiro",
        // …
    ]
    // `tokens` are only needed for `RRule.fromText`

};


// Strings
var portugueseStrings = {
    'every': 'cada',
    'until': 'até',
    'day': 'dia',
    'days': 'dias',
    'week': 'semana',
    'weeks': 'semanas',
    'on': 'em'
    // …
};

var gettext =  function(id) {
    // Return pt. string, default to english.
    return portugueseStrings[id] || id;
};


var rule = new RRule(RRule.WEEKLY, {
    interval: 5,
    byweekday: [RRule.MO, RRule.FR],
    dtstart: new Date(2012, 1, 1, 10, 30),
    until: new Date(2012, 12, 31)
});

console.log(rule.toText());
// => every 5 weeks on Monday, Friday until January 31, 2013

console.log(rule.toText(null, gettext, portuguese));
// => cada 5 semanas em Segunda-Feira, Sexta-feira até Janeiro 31, 2013

TODO: improve and document the API (perhaps a Language class would be nice).

@Prinzhorn
Copy link
Contributor Author

The API isn't very nice.

Hm, yeah. There's something missing. Because you can't just translate the words. Depending on the language the order needs to be changed as well, because they have a different grammar. Instead there should be format strings like

singular: 'every week on {{dayNames}}',
plural: 'every {{numWeeks}} weeks on {{dayNames}}'

That's just a rough example. I know that there are a lot edge cases etc. and that it's probably hard to do right.

@Prinzhorn
Copy link
Contributor Author

Just came across https://github.com/airbnb/polyglot.js , but there are many other solutions for i18n

Some thing that just bit me:

In English it's "every week" and "every month". In German it's "jede Woche" and "jeden Monat". Notice the "n". I can't just translate "every", it won't work.

Similar thing with passing "st" or "rd" to gettext. It doesn't make any sense.

@Prinzhorn
Copy link
Contributor Author

Any news or plans? Now that I started using DTSTART and UNTIL I can't use the toText method anymore. Before that I was able to hack around the current implementation.

One more thing for the list: Date formats. I want DD.MM.YYYY and not MMMM DD, YYYY.

@elecoest
Copy link

I don't understand. In one html file I have this code whith the latests release (2.0).

[code]
<!doctype html>

<title>trad tests</title> <script src="rrule.js"></script> <script src="nlp.js"></script> <script src="underscore.js"></script> <script type='text/javascript'> // Date-related translations var portuguese = { dayNames: [ "Domingo", "Segunda-Feira", "Terça-feira", "Quarta-feira", "Quinta-feira", "Sexta-feira", "Sábado" ], monthNames: [ "Janeiro", "Fevereiro", // … ] // `tokens` are only needed for `RRule.fromText` }; // Strings var portugueseStrings = { 'every': 'cada', 'until': 'até', 'day': 'dia', 'days': 'dias', 'week': 'semana', 'weeks': 'semanas', 'on': 'em' // … }; var gettext = function(id) { // Return pt. string, default to english. return portugueseStrings[id] || id; }; var rule = new RRule(RRule.WEEKLY, { interval: 5, byweekday: [RRule.MO, RRule.FR], dtstart: new Date(2012, 1, 1, 10, 30), until: new Date(2012, 12, 31) }); console.log(rule.toText()); // => every 5 weeks on Monday, Friday until January 31, 2013 console.log(rule.toText(null, gettext, portuguese)); // => cada 5 semanas em Segunda-Feira, Sexta-feira até Janeiro 31, 2013 </script>

[/code]
It's doesn't work with the error :

TypeError: _ is undefined
var defaults = _.clone(RRule.DEFAULT_OPTIONS);
in rrule at line 463.

Where I am in wrong ?

@sberryman
Copy link

You need another library called underscorejs. I'm on my phone otherwise I would have given you a link.

On Oct 30, 2013, at 11:54 PM, elecoest notifications@github.com wrote:

I don't understand. In one html file I have this code whith the latests release (2.0).

<!doctype html>

trad tests
It's doesn't work woth the error :

TypeError: _ is undefined

var defaults = .clone(RRule.DEFAULTOPTIONS);
in rrule at line 463.

Where I am in wrong ?


Reply to this email directly or view it on GitHub.

@elecoest
Copy link

ok, i'd placed undesrcore.js in third position...
I've place underscore.js in first position.
Now i'vva error
TypeError: 2 is not an object
return result.call(this, func.apply(_, args));
in underscore.js

@elecoest
Copy link

elecoest commented Nov 1, 2013

Sorry but this way is ak for every body ?

Nobody has this error before ?

Thanks a lot for your help.

@creamteam-de
Copy link

What's the meaning of the today parameter?

It's not actually used as of now, you can just pass null.

Which values are passed to gettext?
How do I actually translate stuff? I'm able to change dayNames and monthNames, but that's only part of it.

The API isn't very nice.

You need to create a language definition with date related stuff. The default English one is here. tokens are only needed for RRule.fromText.

gettext gets the English string (you can see what strings are used here).

A crude example (you need the current master, older versions cached the output of toText):

// Date-related translations
var portuguese = {
    dayNames: [
        "Domingo",
        "Segunda-Feira",
        "Terça-feira",
        "Quarta-feira",
        "Quinta-feira",
        "Sexta-feira",
        "Sábado"
    ],
    monthNames: [
        "Janeiro",
        "Fevereiro",
        // …
    ]
    // `tokens` are only needed for `RRule.fromText`

};


// Strings
var portugueseStrings = {
    'every': 'cada',
    'until': 'até',
    'day': 'dia',
    'days': 'dias',
    'week': 'semana',
    'weeks': 'semanas',
    'on': 'em'
    // …
};

var gettext =  function(id) {
    // Return pt. string, default to english.
    return portugueseStrings[id] || id;
};


var rule = new RRule(RRule.WEEKLY, {
    interval: 5,
    byweekday: [RRule.MO, RRule.FR],
    dtstart: new Date(2012, 1, 1, 10, 30),
    until: new Date(2012, 12, 31)
});

console.log(rule.toText());
// => every 5 weeks on Monday, Friday until January 31, 2013

console.log(rule.toText(null, gettext, portuguese));
// => cada 5 semanas em Segunda-Feira, Sexta-feira até Janeiro 31, 2013

TODO: improve and document the API (perhaps a Language class would be nice).

Hi, I'm trying to get i18n for german, but I can not find what strings are used in "gettext" since the link is broken. I tried to look on the sources but I could find it anything.

Thanks!

@AlexanderKosianchuk
Copy link

What's the meaning of the today parameter?

It's not actually used as of now, you can just pass null.

Which values are passed to gettext?
How do I actually translate stuff? I'm able to change dayNames and monthNames, but that's only part of it.

The API isn't very nice.
You need to create a language definition with date related stuff. The default English one is here. tokens are only needed for RRule.fromText.
gettext gets the English string (you can see what strings are used here).
A crude example (you need the current master, older versions cached the output of toText):

// Date-related translations
var portuguese = {
    dayNames: [
        "Domingo",
        "Segunda-Feira",
        "Terça-feira",
        "Quarta-feira",
        "Quinta-feira",
        "Sexta-feira",
        "Sábado"
    ],
    monthNames: [
        "Janeiro",
        "Fevereiro",
        // …
    ]
    // `tokens` are only needed for `RRule.fromText`

};


// Strings
var portugueseStrings = {
    'every': 'cada',
    'until': 'até',
    'day': 'dia',
    'days': 'dias',
    'week': 'semana',
    'weeks': 'semanas',
    'on': 'em'
    // …
};

var gettext =  function(id) {
    // Return pt. string, default to english.
    return portugueseStrings[id] || id;
};


var rule = new RRule(RRule.WEEKLY, {
    interval: 5,
    byweekday: [RRule.MO, RRule.FR],
    dtstart: new Date(2012, 1, 1, 10, 30),
    until: new Date(2012, 12, 31)
});

console.log(rule.toText());
// => every 5 weeks on Monday, Friday until January 31, 2013

console.log(rule.toText(null, gettext, portuguese));
// => cada 5 semanas em Segunda-Feira, Sexta-feira até Janeiro 31, 2013

TODO: improve and document the API (perhaps a Language class would be nice).

Hi, I'm trying to get i18n for german, but I can not find what strings are used in "gettext" since the link is broken. I tried to look on the sources but I could find it anything.

Thanks!

https://github.com/jakubroztocil/rrule/tree/master/src/nlp

@ghost
Copy link

ghost commented May 29, 2019

Would be nice to have some documentation how to use it. I've translated to german, but it's looks wrong:

const germanStrings = {
    every: 'jedes',
    until: 'bis',
    day: 'Tag',
    days: 'Tage',
    week: 'Woche',
    weeks: 'Wochen',
    on: 'ein',
    in: 'in',
    'on the': 'auf dem',
    for: 'für',
    and: 'und',
    or: 'oder',
    at: 'bei',
    last: 'zuletzt',
    '(~ approximate)': '(~ approximativ)',
    times: 'Zeiten',
    time: 'Zeit',
    minutes: 'Minuten',
    hours: 'Stunden',
    weekdays: 'Wochentage',
    weekday: 'Wochentag',
    months: 'Monate',
    month: 'Monat',
    years: 'Jahre',
    year: 'Jahr'
  };
const RRULE_GERMAN = {
  dayNames: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'],
  monthNames: [
    'Januar',
    'Februar',
    'März',
    'April',
    'Mai',
    'Juni',
    'Juli',
    'August',
    'September',
    'Oktober',
    'November',
    'Dezember'
  ]
};
const gettext = id => {
    return germanStrings[id] || id;
};

const rruleText = rule.toText(id => {
    gettext(id);
}, RRULE_GERMAN);

@ghost
Copy link

ghost commented Dec 9, 2019

Any updates? How to translate text to other language?

@gongAll
Copy link

gongAll commented Feb 4, 2020

I think the i18n of this library, as of now, is fundamentally flawed. Things like

nth_monthday' => array(
		'1' => 'the 1st',
		'2' => 'the 2nd',
		'3' => 'the 3rd',
		'21' => 'the 21st',
		'22' => 'the 22nd',
		'23' => 'the 23rd',
		'31' => 'the 31st',
		'else' => 'the %{n}th'
	),

are absolutely necessary for some final user experience usage, in different languages. I'd recommend implementing the logic in this alternative (as mentioned by @wakirin in this post). It would really bring the usage of this library up, since, at this moment, this logic must be done manually, in order to create some usable i18n logic.

UPDATE: after crawling the code, I found a way to do what I wanted, which, for my language, "solved" it. Just for future reference, I'll leave here a list of all the keys you must translate on the getText method you pass on.

 '(~ approximate)'
 'and'
 'at'
 'day'
 'days'
 'every'
 'for'
 'hour'
 'hours'
 'in'
 'last'
 'minutes'
 'month'
 'months'
 'nd'
 'on the'
 'on'
 'or'
 'rd'
 'st'
 'th'
 'the'
 'time'
 'times'
 'until'
 'week'
 'weekday'
 'weekdays'
 'weeks'
 'weeks'
 'year'
 'years'
 'RRule error: Unable to fully convert this rrule to text'

@Mistes974
Copy link

Mistes974 commented May 26, 2020

@gongAll Thanks,
With your example, I was able to use moment.js and i18n, as below:

export const RRuleToText = ({ strRRule }) => {
  const language = {
    dayNames: moment.weekdays(),
    monthNames: moment.months()
  };

  const getText = id => {
    return i18n.t(`vendor.rrule.${id}`, id);
  };

  const dateFormat = (year, month, day) =>
    moment()
      .date(day)
      .year(year)
      .month(month)
      .format("LL");

  return strRRule
    ? capitalize(
        RRule.fromString(strRRule).toText(getText, language, dateFormat)
      )
    : "";
};

@suzumejakku
Copy link

suzumejakku commented Feb 20, 2021

Will there be an update on this matter ? I have to translate into Japanese; the words order is significantly different, so I have no idea how to proceed...

@shivakumars
Copy link

I have followed the examples given in the thread, but unfortunately, I'm getting a JS error. Can someone help?

Screenshot 2021-05-07 at 4 57 49 PM

happens when I make a call using below code,
console.log(rule.toText(null, gettext, portuguese));

@ghost
Copy link

ghost commented May 7, 2021

@shivakumars t is related to i18n library (https://www.i18next.com/overview/api#t). You need to use your translation library or remove it.

@shivakumars
Copy link

@shivakumars t is related to i18n library (https://www.i18next.com/overview/api#t). You need to use your translation library or remove it.

I tried adding the mentioned library as a dependency, still getting the error. Can you help me with an example, please.

@ghost
Copy link

ghost commented May 7, 2021

const yourStrings = {every: 'jedes',
    until: 'bis',
    day: 'Tag',
    days: 'Tage',
    week: 'Woche',
    weeks: 'Wochen',
    on: 'ein',
    in: 'in',
    'on the': 'auf dem',
    for: 'für',
    and: 'und',
    or: 'oder',
    at: 'bei',
    last: 'zuletzt',
    '(~ approximate)': '(~ approximativ)',
    times: 'Zeiten',
    time: 'Zeit',
    minutes: 'Minuten',
    hours: 'Stunden',
    weekdays: 'Wochentage',
    weekday: 'Wochentag',
    months: 'Monate',
    month: 'Monat',
    years: 'Jahre',
    year: 'Jahr'
};
export const RRuleToText = ({ strRRule }) => {
  const language = {
    dayNames: moment.weekdays(),
    monthNames: moment.months()
  };

  const getText = id => {
    return yourStrings[id];
  };

  const dateFormat = (year, month, day) =>
    moment()
      .date(day)
      .year(year)
      .month(month)
      .format("LL");

  return strRRule
    ? capitalize(
        RRule.fromString(strRRule).toText(getText, language, dateFormat)
      )
    : "";
};

@shivakumars
Copy link

const yourStrings = {every: 'jedes',
    until: 'bis',
    day: 'Tag',
    days: 'Tage',
    week: 'Woche',
    weeks: 'Wochen',
    on: 'ein',
    in: 'in',
    'on the': 'auf dem',
    for: 'für',
    and: 'und',
    or: 'oder',
    at: 'bei',
    last: 'zuletzt',
    '(~ approximate)': '(~ approximativ)',
    times: 'Zeiten',
    time: 'Zeit',
    minutes: 'Minuten',
    hours: 'Stunden',
    weekdays: 'Wochentage',
    weekday: 'Wochentag',
    months: 'Monate',
    month: 'Monat',
    years: 'Jahre',
    year: 'Jahr'
};
export const RRuleToText = ({ strRRule }) => {
  const language = {
    dayNames: moment.weekdays(),
    monthNames: moment.months()
  };

  const getText = id => {
    return yourStrings[id];
  };

  const dateFormat = (year, month, day) =>
    moment()
      .date(day)
      .year(year)
      .month(month)
      .format("LL");

  return strRRule
    ? capitalize(
        RRule.fromString(strRRule).toText(getText, language, dateFormat)
      )
    : "";
};

Thank you 🙏 . This worked.

@fishdevClassFunc
Copy link

const yourStrings = {every: 'jedes',
    until: 'bis',
    day: 'Tag',
    days: 'Tage',
    week: 'Woche',
    weeks: 'Wochen',
    on: 'ein',
    in: 'in',
    'on the': 'auf dem',
    for: 'für',
    and: 'und',
    or: 'oder',
    at: 'bei',
    last: 'zuletzt',
    '(~ approximate)': '(~ approximativ)',
    times: 'Zeiten',
    time: 'Zeit',
    minutes: 'Minuten',
    hours: 'Stunden',
    weekdays: 'Wochentage',
    weekday: 'Wochentag',
    months: 'Monate',
    month: 'Monat',
    years: 'Jahre',
    year: 'Jahr'
};
export const RRuleToText = ({ strRRule }) => {
  const language = {
    dayNames: moment.weekdays(),
    monthNames: moment.months()
  };

  const getText = id => {
    return yourStrings[id];
  };

  const dateFormat = (year, month, day) =>
    moment()
      .date(day)
      .year(year)
      .month(month)
      .format("LL");

  return strRRule
    ? capitalize(
        RRule.fromString(strRRule).toText(getText, language, dateFormat)
      )
    : "";
};

How to setup this?

@cleverfleet
Copy link

cleverfleet commented Feb 7, 2022

const strings = {
  every: 'alle',
  until: 'endet am',
  day: 'Tag',
  days: 'Tage',
  week: 'Wochen',
  weeks: 'Wochen',
  on: 'am',
  in: 'in',
  'on the': 'am',
  for: 'für',
  and: 'und',
  or: 'oder',
  at: 'bei',
  last: 'zuletzt',
  st: '.,',
  nd: '.,',
  rd: '.,',
  th: '.,',
  '(~ approximate)': '(~ ungefähr)',
  times: 'Zeiten',
  time: 'Zeit',
  minutes: 'Minuten',
  hours: 'Stunden',
  weekdays: 'Wochentag',
  weekday: 'Wochentag',
  months: 'Monate',
  month: 'Monate',
  years: 'Jahre',
  year: 'Jahre'
}
export default {
  getText: (id) => strings[id] || id,
  language: {
    dayNames: [
      'Sonntag',
      'Montag',
      'Dienstag',
      'Mittwoch',
      'Donnerstag',
      'Freitag',
      'Samstag'
    ],
    monthNames: [
      'Januar',
      'Februar',
      'März',
      'April',
      'Mai',
      'Juni',
      'Juli',
      'August',
      'September',
      'Oktober',
      'November',
      'Dezember'
    ]
  },
  dateFormat: (year, month, day) => `${day}. ${month} ${year}`
}

// rule.toText(getText, language, dateFormat)

I think these could be better translation options.

  • no need for momentjs
  • "every" is hard to translate as different for day/week/year, so simpler "all"
  • 1st, 2nd, 3rd etc were missing, but simplest in german is a ".". To better diffirentiate with "until" added a comma there too
  • stangely enough some singular/plural forms are the same even is not correct but for the sentences are fitting better
  • until more clearly translated as "ends on"

I have not tested every possibility as only use daily weekly or yearly stuff. Also noted that things like "every third monday every month ..." is no included at all yet?

@marcosandri-dev
Copy link

const yourStrings = {every: 'jedes',
    until: 'bis',
    day: 'Tag',
    days: 'Tage',
    week: 'Woche',
    weeks: 'Wochen',
    on: 'ein',
    in: 'in',
    'on the': 'auf dem',
    for: 'für',
    and: 'und',
    or: 'oder',
    at: 'bei',
    last: 'zuletzt',
    '(~ approximate)': '(~ approximativ)',
    times: 'Zeiten',
    time: 'Zeit',
    minutes: 'Minuten',
    hours: 'Stunden',
    weekdays: 'Wochentage',
    weekday: 'Wochentag',
    months: 'Monate',
    month: 'Monat',
    years: 'Jahre',
    year: 'Jahr'
};
export const RRuleToText = ({ strRRule }) => {
  const language = {
    dayNames: moment.weekdays(),
    monthNames: moment.months()
  };

  const getText = id => {
    return yourStrings[id];
  };

  const dateFormat = (year, month, day) =>
    moment()
      .date(day)
      .year(year)
      .month(month)
      .format("LL");

  return strRRule
    ? capitalize(
        RRule.fromString(strRRule).toText(getText, language, dateFormat)
      )
    : "";
};

Works like magic.
For whoever asking, the strRRule is the rule you have created with new Rule, rule.toString().
You can also use dayjs bu adding the LocaleData plugin.
Also, if you get an error for the tokens you can pass an empty object: {} or you can find them here: https://github.com/jakubroztocil/rrule/blob/master/src/nlp/i18n.ts

@ShacharRatzabi
Copy link

@sberryman @jakubroztocil @Prinzhorn @shivakumars @elecoest
did you find any solution for this?

I'm using rrule.toText() to get a human text of a frequency, and I need to support multiple languages

@scriptify
Copy link

So the behavior indeed seems a bit odd. I tried copying the dictionary from the i18n.ts file and replicating it in different languages, then passing it to the toText method as the second parameter.

So while the week/month names get correctly translated, the rest doesn't.

The oddity, IMO, starts with the getText function which can be passed as the first parameter.

This function returns translations for different parts of the stringified RRule, e.g. "every" or "for".

The default implementation of this function solely returns id.toString(), while id is the default English word of the expression.

So it turns out, the library itself doesn't even seem to make use of the Regular Expressions inside language.tokens.

To make it work correctly, I created a custom getText implementation which returns the translated version of the id.

So theoretically, we could just translate each ID to our desired language.

So a possible solution would be:

import { RRule } from 'rrule';

interface Language {
  dayNames: string[];
  monthNames: string[];
  tokens: {
    [k: string]: RegExp;
  };
  getTextDict: { [k: string]: string }
}

const GERMAN: Language = {
  dayNames: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'],
  monthNames: [
    'Januar',
    'Februar',
    'März',
    'April',
    'Mai',
    'Juni',
    'Juli',
    'August',
    'September',
    'Oktober',
    'November',
    'Dezember',
  ],
  tokens: {
    ...
  },
 getTextDict: {
    th: '.',
    every: 'alle',
    days: 'tage',
    weekdays: 'werktage',
    weeks: 'wochen',
    hours: 'stunden',
    minutes: 'minuten',
    months: 'monate',
    years: 'jahre',
    day: 'tag',
    weekday: 'werktag',
    week: 'woche',
    hour: 'stunde',
    minute: 'minute',
    month: 'monat',
    year: 'jahr',
    on: 'am',
    'on the': 'am',
    at: 'um',
    the: 'der',
    first: 'erste',
    second: 'zweite',
    third: 'dritte',
    last: 'letzter',
    for: 'für',
    time: 'mal',
    times: 'mal',
    until: 'bis',
  }
};



export function stringifyRepetition(
  rrule: RRuleConfig,
  language: 'en'  | 'de'
) {
  const rrule = new RRule(rrule);

  if (language === 'en') {
    return rrule.toText();
  }

  const langStrings = GERMAN;

  const getText = (id: any) => {
    return langStrings.tokens[id] || id.toString();
  };

  return rrule.toText(getText, langStrings);
}

Unfortunately, this approach doesn't work well with e.g. German, as words cannot be just replaced with their german equivalent.

The tokens prop of the language objects is quite confusing. This object is not used to stringify values, but to parse strings into RRules.

So I fear the only viable solution is to roll your own implementation.
Or did I miss anything?

@PierrickP
Copy link

PierrickP commented Mar 28, 2024

I'm going to add a coin to this issue.

I needed to translate the result of toText().
As other people have pointed out, you can't just translate words individually.
Passing a function to toText() would give an imperfect result.

My needs were limited. I've limited myself to freq / until / count / interval options. byweekday / bymonth seem accessible.

I preferred to rely on a true i18n lib, intl-messageformat (which is used in the highest-level lib I use, svelte-i18n).
The important thing is that it's based on a standardized format, icu messages (https://unicode-org.github.io/icu/userguide/format_parse/messages/).

I made a small function to correctly pass values (directly based on an instance of RRule)

// $format is the svelte-i18n method to get translation
// $date same for date

export function humanizeRRule(rule) {
  return $format(`humanized rrule`, {
    values: {
      freq: freqEnum[rule.options.freq],
      localizedFreq: $format(freqEnum[rule.options.freq], {
        values: { interval: rule.options.interval },
      }),
      count: $format("{count}", { values: { count: rule.options.count || 0 } }),
      until:
        rule.options.until && $date(rule.options.until, { dateStyle: "long" }),
    },
  });
}

freq is pass as key and translation, count and util as translations

And most important is the translation keys.
⚠️ It's not prefect, i'm not fluent in any languages.

In English

{
  "humanized rrule": "{freq, select, other {every} } {localizedFreq}{count}{until, select, null {} false {} other { until {until}}}",
  "{count}": "{count, plural, =0 {} =1 { 1 time} other { # times}}",
  "YEARLY": "{interval, plural, =1 {year} other {# years}}",
  "MONTHLY": "{interval, plural, =1 {month} other {# months}}",
  "WEEKLY": "{interval, plural, =1 {week} other {# weeks}}",
  "DAILY": "{interval, plural, =1 {day} other {# days}}",
  "HOURLY": "{interval, plural, =1 {hour} other {# hours}}",
  "MINUTELY": "{interval, plural, =1 {minute} other {# minutes}}",
  "SECONDLY": "{interval, plural, =1 {second} other {# seconds}}"
}

image

French

{
  "humanized rrule": "{freq, select, YEARLY {tous les} MONTHLY {tous les} WEEKLY {toutes les} DAILY {tous les} HOURLY {toutes les} MINUTELY {toutes les} SECONDLY {toutes les} other {} } {localizedFreq}{count}{until, select, null {} false {} other {, jusqu'au {until}}}",
  "{count}": "{count, plural, =0 {} =1 {, 1 fois} other {, # fois}}",
  "YEARLY": "{interval, plural, =1 {ans} other {# ans}}",
  "MONTHLY": "{interval, plural, =1 {mois} other {# mois}}",
  "WEEKLY": "{interval, plural, =1 {semaines} other {# semaines}}",
  "DAILY": "{interval, plural, =1 {jours} other {# jours}}",
  "HOURLY": "{interval, plural, =1 {heures} other {# heures}}",
  "MINUTELY": "{interval, plural, =1 {minutes} other {# minutes}}",
  "SECONDLY": "{interval, plural, =1 {secondes} other {# secondes}}"
}

image

And more exotic, Chinese

(mix between Arabic and Chinese number. It can certainly be improved)

{
  "humanized rrule": "{freq, select, other {每} }{localizedFreq}{count}{until, select, null {} false {} other {直到{until}}}",
  "{count}": "{count, plural, =0 {} =1 {1次} other {一共#次}}",
  "YEARLY": "{interval, plural, =1 {年} other {#年一次}}",
  "MONTHLY": "{interval, plural, =1 {月} other {#月一次}}",
  "WEEKLY": "{interval, plural, =1 {周} other {#周一次}}",
  "DAILY": "{interval, plural, =1 {天} other {#天一次}}",
  "HOURLY": "{interval, plural, =1 {小时} other {#小时一次}}",
  "MINUTELY": "{interval, plural, =1 {分钟} other {#分钟一次}}",
  "SECONDLY": "{interval, plural, =1 {秒} other {#秒一次}}"
}

image

I'm pretty sure we can adapt it to german or other language and continue to implement others options.

@dBianchii
Copy link

I need this as well...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests