Search code examples
phplaravelmultilingual

Ordinal indicators in different languages in PHP


I'm developing a multi-language website in PHP Laravel and I need to print on screen some sentences that shows numbers followed by an ordinal indicator.

The website is in English, Spanish, German, French, Italian, Portuguese, Russian, Polish.

I'm wondering if exist a way in php that can support me with the generation of the ordinal numbers in the different languages. Or some suggestions about how you would address this problem.

I spent quite some time googling but I didn't find any solution yet.

eg.

  • English: 1st, 2nd, 3rd, ..
  • Italian: 1°, 2°, 3°, ..
  • French: 1er, 2e, 3e, ..
  • Spanish: 1°, 2°, 3°, ..
  • Portuguese: 1°, 2°, 3°, ..
  • German: 1., 2., 3., ..
  • Russian: 1-й, 2-й, 3-й, ...
  • Polish: 1, 2, 3, ..

Solution

  • PHP has a NumberFormatter class that you can use to format number for different locales.

    You can create a formatter like:

    $formatter = new \NumberFormatter("en-US", \NumberFormatter::ORDINAL);
    

    and use it with $formatter->format(3);.

    Here are some locales that I tried:

    >>> $a = new \NumberFormatter("it-IT", \NumberFormatter::ORDINAL);
    => NumberFormatter {#3199
         locale: "it",
         pattern: """
           %%dord-mascabbrev:\n
           0: º;\n
           %digits-ordinal-masculine:\n
           0: =#,##0==%%dord-mascabbrev=;\n
           -x: −>%digits-ordinal-masculine>;\n
           %%dord-femabbrev:\n
           0: ª;\n
           %digits-ordinal-feminine:\n
           0: =#,##0==%%dord-femabbrev=;\n
           -x: −>%digits-ordinal-feminine>;\n
           %digits-ordinal:\n
           0: =%digits-ordinal-masculine=;\n
           """,
          …3
       }
    >>> $a->format(12)
    => "12º"
    >>> $a = new \NumberFormatter("en-US", \NumberFormatter::ORDINAL);
    => NumberFormatter {#3197
         locale: "en",
         pattern: """
           %digits-ordinal:\n
           0: =#,##0=$(ordinal,one{st}two{nd}few{rd}other{th})$;\n
           -x: −>%digits-ordinal>;\n
           """,
          …3
       }
    >>> $a->format(12)
    => "12th"
    >>> $a = new \NumberFormatter("fr-FR", \NumberFormatter::ORDINAL);
    => NumberFormatter {#3188
         locale: "fr",
         pattern: """
           %digits-ordinal-masculine:\n
           0: =#,##0=$(ordinal,one{er}other{e})$;\n
           -x: −>%digits-ordinal-masculine>;\n
           %digits-ordinal-feminine:\n
           0: =#,##0=$(ordinal,one{re}other{e})$;\n
           -x: −>%digits-ordinal-feminine>;\n
           %digits-ordinal-masculine-plural:\n
           0: =#,##0=$(ordinal,one{ers}other{es})$;\n
           -x: −>%digits-ordinal-masculine-plural>;\n
           %digits-ordinal-feminine-plural:\n
           0: =#,##0=$(ordinal,one{res}other{es})$;\n
           -x: −>%digits-ordinal-feminine-plural>;\n
           %digits-ordinal:\n
           0: =%digits-ordinal-masculine=;\n
           """,
          …3
       }
    >>> $a->format(12)
    => "12e"