Pull to refresh

Intl к нам приходит!

Reading time 4 min
Views 30K
datemap Нет, не Intel. Intl — JavaScript объект, содержащий в себе функции форматирования чисел, дат и сравнения строк. Приходит, потому что 29 апреля Firefox, последний из популярных браузеров, не поддерживающий Intl, обновляется до 29 версии, в которой поддержка интернационализации будет включена.

Разумеется, тем кому приходится волею судеб поддерживать старые браузеры, опять не повезло. Но прогресс не стоит на месте и, начиная с конца апреля, счастливчикам можно будет потихоньку внедрять Intl в свои проекты.

Что же даёт Intl JS программисту?



Объект Intl содержит в себе три свойства:
  • Intl.Collator — Конструктор класса позволяющего производить сравнения строк с учётом локали.
  • Intl.DateTimeFormat — Конструктор класса позволяющего форматировать дату и время с учетом локали
  • Intl.NumberFormat — Конструктор класса содержащего функции форматирования чисел. В соответствии с локалью, разумеется.


Все конструкторы принимают два параметра — locale и options.
Первый аргумент — строка определяющая локаль, например «hi», «ru-RU», «de-DE-u-co-phonebk», второй — объект, в зависимости от конструктора содержащий набор необходимых настроек. Собственно, объекты могут создаваться при помощи
new Intl.Collator([locales [, options]]) 
но функции могут быть применены и к существующим объектам при помощи
Intl.Collator.call(this [, locales [, options]])
Теперь по порядку

Collator


Случалось ли вам сравнивать строки? Ай ай ай, не нужно помидорами швыряться, ну конечно да! А строки с эм… кракозяблами? Смотрим:
console.log(new Intl.Collator("de", {sensitivity: "base"}).compare("ä", "a"));  // 0
console.log(new Intl.Collator("sv", {sensitivity: "base"}).compare("ä", "a"));  // 1
Да, шведский и немецкий языки имеют разный алфавит. Опция sensitivity как раз отвечает за взаимопонимание и может принимать следующие значения:
"base" // a ≠ b, a = á, a = A.
"accent" // a ≠ b, a ≠ á, a = A.
"case" // a ≠ b, a = á, a ≠ A.
"variant" // a ≠ b, a ≠ á, a ≠ A. 


Сортировка строк может осуществляться с учетом числовых значений:
console.log(new Intl.Collator("ru", {numeric: true}).compare("3", "21"));  // -1
console.log(new Intl.Collator("ru", {numeric: false}).compare("3", "21")); // 1

Кстати, в опциях есть еще параметр usage, с возможными значениями sort и search, который так же влияет на сравнение, но я не ставлю задачей этой статьи полностью описать объект Intl, всё равно лучше чем в документации — не получится.

Очень удобной опцией является ignorePunctuation. Название говорит само за себя и нуждается только в показательном примере:
console.log(new Intl.Collator("ru", {ignorePunctuation: true}).compare("привет!", "привет")); // 0
console.log(new Intl.Collator("ru", {ignorePunctuation: false}).compare("привет!", "привет")); // 1


Далее в программе:

DateTimeFormat


Не знаю как для вас, но для меня форматирование дат — настоящая головная боль. Если вам посчастливилось избежать такой задачи, откройте, например, Excel и в настройках форматирования ячейки посчитайте количество предопределённых форматов. Прибавьте к этому зависимость от локали с картинки в начале поста, и будет вам счастье. Конечно, до определённого момента спасает что ни-будь вроде moment.js или XDate. Но как же приятно иметь такое в найтивном объекте! Посмотрим поближе:

timeZone Браузеры обязаны понимать только UTC, но могут поддерживать и другие временные зоны. К сожалению, это остаётся на совести разработчиков.

hour12 Объяснений, я думаю, не требует. Скажу только, что значение по умолчанию зависит от локали. Приятно то как!

Вместо описания остальных опций, которое можно найти в документации, приведу несколько примеров:
var date = new Date();
console.log(new Intl.DateTimeFormat("de-DE", {
  weekday: "long", 
  year: "numeric", 
  month: "long", 
  day: "numeric"}).format(date));
// Samstag, 5. April 2014 

console.log(new Intl.DateTimeFormat("ru", {
  weekday: "short", 
  year: "2-digit", 
  month: "long", 
  day: "numeric"}).format(date));
// сб, 5 апреля 14 г.

console.log(new Intl.DateTimeFormat("ar-EG", {
  weekday: "narrow", 
  year: "numeric", 
  month: "long", 
  day: "numeric"}).format(date));
// ٢٠١٤  тут хабрапарсер может слопать часть значения, так что запустите это в консоли


NumberFormat


Ну это просто праздник какой-то!
Например, требуется вывести число с незначащими нулями впереди. Обычная практика это преобразование числа в строку и приписывание необходимого количества нулей в её начало. Плясок с бубном добавляет необходимость выводить в таком виде отрицательный числа. Всё. Про это можно забыть.
console.log(new Intl.NumberFormat("ru-RU",{minimumIntegerDigits: 7}).format(-123)); // -0 000 123 


Так же обстоят дела и со знаками после запятой, но параметров здесь два:
console.log(new Intl.NumberFormat("ru-RU",{minimumIntegerDigits: 7, minimumFractionDigits: 5, maximumFractionDigits: 7}).format(-12.345)); 
// -0 000 012,34500  
По умолчанию maximumFractionDigits имеет значение 3 и по этому забывать про него не стоит.

Кстати, заметили? Цифры сгруппированы в разряды. Отключить такое поведение можно выставив опцию useGrouping в false
console.log(new Intl.NumberFormat("ru-RU",{minimumIntegerDigits: 7, useGrouping: false}).format(-12.345));
// -0000012,345


Ну и напоследок совсем невероятная вещь. Деньги!
Хотите в евро?
console.log(new Intl.NumberFormat("de-DE", {style: "currency", currency: "EUR"}).format(12.345)); // 12,345 € 

Или может в йенах?
console.log(new Intl.NumberFormat("ja-JP", {style: "currency", currency: "JPY"}).format(12.345)); //¥12.345 

Или может быть в евро, но на японский манер?
console.log(new Intl.NumberFormat("ja-JP", {style: "currency", currency: "EUR"}).format(12.345)); // €12.345 

Есть еще и другие параметры, но, опять же, документация скажет лучше чем я.

Заключение


Надеюсь, вы впечатлены демонстрацией. Что касается меня, я в абсолютном восторге и c нетерпением жду выхода 29-го Огнелиса. Я больше не могу поддерживать старые браузеры. Душа к антиквариату и так не лежала, но после введения Intl повсеместно, было бы очень обидно не пользоваться им только потому что кому то лень нажать кнопку «обновить браузер».
Статья написана по мотивам документации:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl
Tags:
Hubs:
+70
Comments 28
Comments Comments 28

Articles