Форматировать цифры, время, валюты и другое с Formatters

Как форматировать значения в Swift при помощи форматтеров. Валюта, дата, фото и другое.

Поможем в Telegram-чате для iOS разработчиков

Она пригодится, если захотите локализовать данные в правильном формате в зависимости от выбранного языка. Например, сумму 3 000,00 ₽, дату 24 апр. 2022 г. или процент 54 %.

 Пример локализации процента на разные языки с помощью форматтера
Пример локализации процента на разные языки с помощью форматтера

Чтобы получить идентификатор локали, вызовите Locale.current.identifier. Вернётся значение языкприложения_ЯЗЫКРЕГИОНА, например, en_US. Полный список таких идентификаторов найдёте по ссылке

Apple используют ISO стандартизацию, поэтому если на устройстве язык, который не соответствует региону, вернутся разные значения. Например, для en_RU вместо вернётся RUB

Дата

Получаем текущую дату:

let currentDate = Date()

Создаём и настраиваем объект DateFormatter:

let dateFormatter = DateFormatter()
// Задаём стиль, например <mark>.medium</mark>
dateFormatter.dateStyle = DateFormatter.Style.medium
dateFormatter.timeStyle = DateFormatter.Style.medium 

// Указываем локаль
dateFormatter.locale = Locale.current

Выводим локализованную дату:

print(dateFormatter.string(from: currentDate))

В консоли будет 24 апр. 2022 г., 02:05:34.

Так же можно создать свой формат даты, вместо стиля:

dateFormatter.setLocalizedDateFormatFromTemplate("MMddyyyy") // Так же доступны часы <mark>HH</mark> и минуты <mark>mm</mark>

В консоли будет 24/04/2022.

Время

Продолжительность

Создаем объект DateComponentsFormatter:

let dateComponentsFormatter = DateComponentsFormatter()

Выбираем стиль и единицы времени для отображения:

dateComponentsFormatter.unitsStyle = .abbreviated // Стиль
dateComponentsFormatter.allowedUnits = [.month, .day, .hour, .minute] // Единицы, при выводе используются нужные. Можно убрать лишние

Доступны разные стили:

  1. .abbreviated - 2 ч 32 мин
  2. .full - 2 часа 32 минуты
  3. .spellOut - два часа тридцать две минуты
  4. .positional - 2:32 (надо убрать лишние allowedUnits)
  5. .short - сокращение (для некоторых языков)
  6. .brief - короче, чем short

Получаем интервал, который будем локализовать:

let interval = Date.current.timeIntervalSince(Date.current.addingTimeInterval(-9132))
let formattedInterval = dateComponentsFormatter.string(from: interval)

Выводим результат:

print(formattedInterval)

Получаем 2 ч 32 мин в консоли.

Отсчет

Создаем объект RelativeDateTimeFormatter:

let relativeDateTimeFormatter = RelativeDateTimeFormatter()

Выбираем стиль:

relativeDateTimeFormatter.unitsStyle = .full

Доступны разные стили:

  1. .full - полное отображение «2 месяца назад»
  2. .short - сокращение «2 мес. назад»
  3. .abbreviated - аббревиатура «-2 м»
  4. .spellOut - разговорное «два месяца назад»
let start = Date.current.addingTimeInterval(-15) // время, от которого считаем сколько прошло
let finish = Date() // время, к которому считаем сколько прошло

let interval = relativeDateTimeFormatter.localizedString(for: start, relativeTo: finish)

Выводим результат:

print(interval)

Получаем 15 секунд назад в консоли. Если поменяем start на Date.current.addingTimeInterval(15) (будущее время), получим через 15 секунд в консоли.

Валюта

Создадим объект NumberFormatter:

let currencyFormatter = NumberFormatter()
currencyFormatter.numberStyle = .currency

Укажем локаль:

currencyFormatter.locale = Locale.current

Получим локализованное значение для 3000:

print(currencyFormatter.string(from: 3000)!)

В консоли будет 3 000,00 ₽.

Дробное число

Создаём и настраиваем объект NumberFormatter:

let numberFormatter = NumberFormatter()
numberFormatter.numberStyle = .decimal

// Указываем локаль
numberFormatter.locale = Locale.current

Выводим локализованное число:

print(numberFormatter.string(from: 123456))

Получаем 123,456 в консоли.

Процент

Создаем число, из которого хотим сделать процент:

let number = 54

// Получаем число с процентом, используя форматтер:
let percent = number.formatted(.percent)

Выводим процент:

print(percent)

Получаем 54 % в консоли.

Расстояние

Создаем объект Measurement:

let measurement = Measurement(
    value: 43.23, // Расстояние
    unit: UnitLength.kilometers // Единица измерения
)
``` 

В <mark>UnitLength</mark> доступно 22 единицы измерения.

Создаем объект <mark>MeasurementFormatter</mark>:

```swift
let measurementFormatter = MeasurementFormatter()

// Выбираем стиль, доступы полный <mark>.long</mark> и сокращенные <mark>.short</mark>, <mark>.medium</mark>
measurementFormatter.unitStyle = .long

Выводим расстояние:

print(measurementFormatter.string(from: measurement))

Получаем 43,23 километра в консоли.

Размер

Создаем объект LengthFormatter

let lengthFormatter = LengthFormatter()

// Выбираем стиль, доступы полный <mark>.long</mark> и сокращенные <mark>.short</mark>, <mark>.medium</mark>
lengthFormatter.unitStyle = .long

Получаем значение:

let value = lengthFormatter.string(fromValue: 14.5, unit: .millimeter)

Доступны разные unit:

  1. millimeter - милиметр
  2. centimeter - сантиметр
  3. meter - метр
  4. kilometer - километр
  5. inch - дюйм
  6. foot - фут
  7. yard - ярд
  8. mile - миля

Выводим размер:

print(value)

Получаем 14,5 миллиметра в консоли.

Энергия

Создаем объект EnergyFormatter:

let energyFormatter = EnergyFormatter()

// Выбираем стиль, доступы полный <mark>.long</mark> и сокращенные <mark>.short</mark>, <mark>.medium</mark>
energyFormatter.unitStyle = .long

Получаем значение:

let value = energyFormatter.string(fromValue: 69.5, unit: .calorie)

Доступны разные unit:

  1. .calorie - калории
  2. .joule - джоули
  3. .kilocalorie - килокалории
  4. .kilojoule - килоджоули

Выводим значение:

print(value)

Получаем 69,5 калории в консоли.

Вес

Создаем объект MassFormatter

let massFormatter = MassFormatter()

// Выбираем стиль, доступы полный <mark>.long</mark> и сокращенные <mark>.short</mark>, <mark>.medium</mark>
massFormatter.unitStyle = .long

Получаем значение:

let value = massFormatter.string(fromValue: 75.2, unit: .kilogram)

Доступны разные unit:

  1. .kilogram - килограмм
  2. .gram - грамм
  3. .pound - фунт
  4. .ounce - унция
  5. .stone - стоун

Выводим вес:

print(value)

Получаем 75,2 килограмма в консоли.

Объем файла

Создаем проперти с объемом файла в байтах:

let number = 54347323

// Получаем локализованный объем файла, используя форматтер:
let byteCount = number.formatted(.byteCount(style: .file))

Выводим объем:

print(byteCount)

Получаем 54.3 МБ в консоли.

Список

Создаём массив, из которого будем делать список:

let list = ["Swift", "Java", "Python"]

Создаём и настраиваем объект ListFormatter:

let listFormatter = ListFormatter()

// Указываем локаль
listFormatter.locale = Locale.current

Выводим локализованный список:

print(listFormatter.string(from: list))

Получаем Swift, Java и Python в консоли. Работает с любым количеством элементов.

Имена

Создаём и настраиваем объект класса PersonNameComponents:

var nameComponents = PersonNameComponents()
nameComponents.familyName = "Петров"
nameComponents.givenName = "Александр"
nameComponents.nameSuffix = "Младший"
nameComponents.nickname = "Саня"

Доступны разные компоненты, например:

  1. namePrefix - часть имени, до основного
  2. givenName - основное имя
  3. nameSuffix - часть имени, после основного
  4. middleName - второе имя
  5. familyName - фамилия
  6. nickname - псевдоним

Создаём объект класса PersonNameComponentsFormatter, с помощью которого будем форматировать имя:

let nameFormatter = PersonNameComponentsFormatter()

Задаем стиль, доступны:

  1. .default и .medium - имя, фамилия
  2. .short - псевдоним
  3. .abbreviated - инициалы имени, фамилии
  4. .long - все компоненты, кроме псевдонима

Выводим результат:

formatter.style = .default // совпадает с <mark>.medium</mark> или отсутствием стиля
print(nameFormatter.string(from: nameComponents))
// В консоли <mark>Александр Петров</mark>

formatter.style = .short
print(nameFormatter.string(from: nameComponents))
// В консоли <mark>Саня</mark>

formatter.style = .abbreviated
print(nameFormatter.string(from: nameComponents))
// В консоли <mark>АП</mark>

formatter.style = .long
print(nameFormatter.string(from: nameComponents))
// В консоли <mark>Александр Младший Петров</mark>
Поправить или дополнить статью через Pull Request