Дата чаще всего внутри представлена в виде Unix-времени (POSIX-время), что в свою очередь является числом прошедщих секунд с 00:00:00 1 января 1970 года в UTC зоне.
Природа Unix-времени порождает некоторые проблемы связанные с ограничениями размерности выбранной для хранения этих секунд.
Дата в человеческом понимании высчитывается из этих секунд на основе часового пояса (Time Zone).
Часовые пояса принято отситчывать он нулевого часового пояса UTC.
Часовые пояса помогают высчитать локальное время от Unix-времени.
Так UTC время 2021-07-12 06:00:00
в московском часовом поясе будет 2021-07-12 09:00:00
потому что московский часовой пояс имеет смещения от UTC в +3 часа.
Смещения часового пояса не всегда выражаются в целых часах, например часовой пояс в Бангалоре, Индия имеет +5 часов и 30 минут.
Важно понимать что локальное время это всегда время в UTC плюс смещение часового пояса по этому 9:00 в Москве является тем же временем, что 14:00 на Бали, в свою очередь оба этих времени являются временем 6:00 в UTC.
Для полноценного отображения даты человеку необходимо учитывать часовой пояс, календарь и локаль.
Западный мир использует григорианский календарь, но мир разный, по всему миру разные народы используют другие календари. 2021 год у нас является 2564 годом в Таиланде.
Напишем простой пример вывода одной и той же даты в разных календарях:
let formatter = DateFormatter()
formatter.dateStyle = .full
let date = Date()
print(date)
for id in calendarIdentifiers {
formatter.calendar = .init(identifier: id)
formatter.calendar.locale = nil
print("\(id):", formatter.string(from: date))
}
Посмотрим на вывод:
2021-07-12 07:08:57 +0000
gregorian: Monday, July 12, 2021
buddhist: Monday, July 12, 2564 BE
chinese: Monday, Sixth Month 3, 2021(xin-chou)
coptic: Monday, Epep 5, 1737 ERA1
ethiopicAmeteMihret: Monday, Hamle 5, 2013 ERA1
ethiopicAmeteAlem: Monday, Hamle 5, 7513 ERA0
hebrew: Monday, 3 Av 5781
iso8601: Monday, July 12, 2021
indian: Monday, Asadha 21, 1943 Saka
islamic: Monday, Dhuʻl-Hijjah 2, 1442 AH
islamicCivil: Monday, Dhuʻl-Hijjah 2, 1442 AH
japanese: Monday, July 12, 3 Reiwa
persian: Monday, Tir 21, 1400 AP
republicOfChina: Monday, July 12, 110 Minguo
islamicTabular: Monday, Dhuʻl-Hijjah 3, 1442 AH
islamicUmmAlQura: Monday, Dhuʻl-Hijjah 2, 1442 AH
Так же локаль влияет на отображение дат, потому что июнь в россии это June у англичан. В каждой стране существует своя нотация записи времени.
В контексте iOS DateFormatter
конвертирует дату в строку и обратно на основе заданого формата и заданных календаря, локали и часового пояса.
Важно понимать что при конвертации дата всегда выражена в Unix-времени, если мы настроим московский часовой пояс для форматера и сконвертируем время "13:00"
мы получим дату 10:00 UTC.