DateIntervalFormatter — основе, форматирање интервала датума

Аутор: IT Sectr Објављено: 2026-07-13 Време читања: 11 мин

DateIntervalFormatter је класа Foundation у iOS и macOS намењена за форматирање опсега датума у локализоване низове: „21–25. јул 2024.“, „од 21. до 25. јула 2024.“ или „Jul 21–25, 2024“. Према Apple Developer Documentation, 2024, DateIntervalFormatter аутоматски одређује које компоненте датума треба понављати (ако је опсег у оквиру једног месеца — месец се приказује једном) и локализује сепараторе и редослед речи. За разлику од ручног лепљења две форматиране датума, ова класа узима у обзир граматичка правила језика: за српски — предлог „до“, за енглески — цртица без предлога. Класа је доступна од iOS 8 и macOS 10.10.

Главно

  • DateIntervalFormatter — класа Foundation за форматирање опсега датума (iOS 8+)
  • Аутоматско груписање — компоненте које се понављају (месец, година) приказују се једном
  • Локализовани сепаратори — уважавање граматичких правила: „од–до“ (српски), цртица (енглески)
  • Три стила датума — .none, .short, .medium, .long, .full за сваки крај опсега
  • Четири стила времена — исти нивои детаља за временски део опсега

Шта је DateIntervalFormatter?

DateIntervalFormatter је подкласа Formatter-а у Foundation-у која прима објекат DateInterval (опсег између два датума) и враћа локализовани низ са описом овог опсега. На пример, за опсег од 21. до 25. јула 2024. резултат ће бити „21–25. јул 2024.“ за sr_RS и „Jul 21–25, 2024“ за en_US. Класа интелигентно групише елементе који се понављају: ако су оба датума у истом месецу, назив месеца се приказује једном.

Основна вредност DateIntervalFormatter-а је аутоматска обрада граматике опсега. Код ручног форматирања, програмер би морао да упореди месец/годину почетка и краја, изабере сепаратор (цртица, „од–до“, „to“, „bis“) и прати деклинацију. DateIntervalFormatter то ради аутоматски на основу CLDR (заједничког репозиторијума локалних података), што смањује број грешака у међународним апликацијама, посебно за језике са сложеном граматиком.

Према Unicode CLDR v44 (2024), правила форматирања опсега датума се значајно разликују између језика. Немачки користи предлог „bis“ (21.–25. Juli 2024), француски — „au“ (du 21 au 25 juillet 2024), јапански — кроз цртицу (2024 Jul 21–25). DateIntervalFormatter покрива све ове варијације без додатног кода на страни програмера.

Како DateIntervalFormatter ради у Foundation-у?

Принцип рада DateIntervalFormatter-а заснива се на анализи два датума који чине опсег и избору оптималног текстуалног приказа узимајући у обзир locale. Класа упоређује компоненте датума (годину, месец, дан) и доноси одлуку о груписању: ако је година иста — приказује се једном; ако је месец исти — приказује се једном; ако се дани разликују — приказује се опсег дана.

Опсегsr_RSen_US
Један дан21. јул 2024.Jul 21, 2024
У оквиру месеца21–25. јул 2024.Jul 21–25, 2024
Различити месеци21. јул – 5. авг 2024.Jul 21 – Aug 5, 2024
Различите године25. дец 2024. – 5. јан 2025.Dec 25, 2024 – Jan 5, 2025
Са временом21. јул 2024, 14:30–16:45Jul 21, 2024, 2:30–4:45 PM

Логика груписања је имплементирана на основу CLDR образаца. Форматер проверава једнакост сваке компоненте датума (Calendar.Component: year, month, day) редом од највеће ка најмањој. Чим компонента постане различита, све мање компоненте се приказују за оба датума. На пример, за 21–25. јул: година се поклапа, месец се поклапа, дан се разликује → месец једном, дани — за сваки датум посебно.

Важан нијанс: DateIntervalFormatter не подржава подешавање сепаратора кроз API. Сепаратор је одређен locale-ом и не може бити прегазан. Ако је потребан прилагођен сепаратор (на пример, „до“ уместо „–“), мораћете да форматирате датуме ручно преко DateFormatter-а и лепите низове са прилагођеним сепаратором.

Стилови форматирања интервала

DateIntervalFormatter пружа два скупа стилова: dateStyle и timeStyle — за сваки крај опсега. Ови стилови раде слично DateFormatter-у: .none сакрива компоненту, .short даје кратак формат (21.07.2024), .medium — средњи (21. јул 2024.), .long — пуни (21. јула 2024.), .full — максимално детаљан (недеља, 21. јул 2024.). Комбиновањем dateStyle и timeStyle могу се добити различити нивои детаља.

Примери комбинација стилова

  • dateStyle = .medium, timeStyle = .none — само датум: „21–25. јул 2024.“
  • dateStyle = .short, timeStyle = .short — датум и време: „21.07.2024, 14:30 – 25.07.2024, 16:45“
  • dateStyle = .none, timeStyle = .short — само време: „14:30–16:45“ (ако су датуми исти)
  • dateStyle = .long, timeStyle = .none — дугачки датум: „21–25. јула 2024.“
  • dateStyle = .full, timeStyle = .short — пуни формат: „недеља, 21. јул 2024. – четвртак, 25. јул 2024.“

Важно: dateStyle и timeStyle се примењују на оба краја опсега једнако. Не може се поставити различит стил за почетак и крај (на пример, .medium за почетак и .short за крај). Ако је потребан различит стил, мораћете да форматирате сваки датум посебним DateFormatter-ом и лепите резултате.

swift
import Foundation

let formatter = DateIntervalFormatter()

// Различите комбинације стилова
let startDate = Date()
let endDate = Date().addingTimeInterval(345600) // +4 дана
let interval = DateInterval(start: startDate, end: endDate)

// Само датум, средњи формат
formatter.dateStyle = .medium
formatter.timeStyle = .none
print("Само датум: \(formatter.string(from: interval))")

// Кратак формат са временом
formatter.dateStyle = .short
formatter.timeStyle = .short
print("Кратак са временом: \(formatter.string(from: interval))")

// Пуни формат
formatter.dateStyle = .full
formatter.timeStyle = .none
print("Пуни датум: \(formatter.string(from: interval))")

DateIntervalFormatter у Swift-у: примери

Основно коришћење DateIntervalFormatter-а укључује креирање инстанце, конфигурисање стилова и позив методе string(from:). Метода прима DateInterval — структуру са start и end особинама. DateInterval се може креирати и од два Date, и иницијализовати са Duration (iOS 16+). Након форматирања, резултат је спреман за приказ у UI-ју без додатне обраде.

swift
import Foundation

let calendar = Calendar.current
let now = Date()

// Примери конкретних интервала
let examples: [(title: String, start: Date, end: Date)] = [
    (
        "2-hour event",
        now,
        now.addingTimeInterval(7200)
    ),
    (
        "Week-long vacation",
        now,
        now.addingTimeInterval(604800)
    ),
    (
        "Cross-year period",
        calendar.date(from: DateComponents(
            year: 2024, month: 12, day: 25
        ))!,
        calendar.date(from: DateComponents(
            year: 2025, month: 1, day: 5
        ))!
    )
]

let intervalFormatter = DateIntervalFormatter()
intervalFormatter.dateStyle = .medium
intervalFormatter.timeStyle = .short

for (title, start, end) in examples {
    let interval = DateInterval(start: start, end: end)
    let result = intervalFormatter.string(from: interval)
    print("\(title): \(result)")
}

// Форматирање преко Calendar (iOS 16+)
if let nextWeek = calendar.date(
    byAdding: .day, value: 7, to: now
) {
    let weekInterval = DateInterval(start: now, end: nextWeek)
    print("Следећих 7 дана: \(intervalFormatter.string(from: weekInterval))")
}

DateIntervalFormatter и Calendar Booking: у апликацијама за резервације (хотели, карте) опсези датума су кључни елемент UI-ја. DateIntervalFormatter исправно обрађује међугодишње опсеге (на пример, од 28. децембра до 3. јануара), групишући месец и годину за сваки датум посебно. За овакве сценарије препоручује се коришћење dateStyle = .medium и timeStyle = .none — најчитљивији формат за датуме без времена.

swift
import Foundation

let formatter = DateIntervalFormatter()
formatter.dateStyle = .long
formatter.timeStyle = .none

// Примери резервација
struct Booking {
    let checkIn: Date
    let checkOut: Date

    var formattedInterval: String {
        let interval = DateInterval(start: checkIn, end: checkOut)
        return formatter.string(from: interval)
    }
}

let booking = Booking(
    checkIn: calendar.date(from: DateComponents(
        year: 2024, month: 7, day: 21
    ))!,
    checkOut: calendar.date(from: DateComponents(
        year: 2024, month: 7, day: 25
    ))!
)
print("Резервација: \(booking.formattedInterval)")

// Коришћење са различитим locale
let enFormatter = DateIntervalFormatter()
enFormatter.dateStyle = .medium
enFormatter.timeStyle = .none
enFormatter.locale = Locale(identifier: "en_US")
print("Енглески: \(enFormatter.string(from: interval))")

DateInterval vs DateIntervalFormatter: DateInterval — структура која представља опсег датума (почетак и крај). DateIntervalFormatter — форматер који претвара ову структуру у низ. DateInterval такође подржава провере contains(Date) и intersection(with:), што је корисно за логику резервација (провера преклапања датума).

Локализација интервала датума

DateIntervalFormatter локализује излаз кроз својство locale. Подразумевано се користи Locale.current — locale уређаја. За приказ интервала на другом језику (на пример, енглески садржај у српском интерфејсу), поставите locale експлицитно. За разлику од DateFormatter-а, DateIntervalFormatter не захтева постављање Locale за серверске податке — увек користи сопствену интерну логику груписања засновану на CLDR.

Језичке разлике у форматирању опсега датума значајно су сложеније него за појединачне датуме. Енглески користи једноставну цртицу: Jul 21–25. Српски — предлог „од–до“: од 21. до 25. јула. Француски — предлог „au“: du 21 au 25 juillet. Немачки — тачка након броја и цртица: 21.–25. Juli. Јапански — кроз цртицу без предлога: Jul 21–25. DateIntervalFormatter покрива све ове варијанте.

swift
import Foundation

let formatter = DateIntervalFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .none

let start = Date()
let end = Date().addingTimeInterval(259200) // +3 дана
let interval = DateInterval(start: start, end: end)

// Приказ различитих locale
let localeIds = ["ru_RU", "en_US", "de_DE", "fr_FR", "ja_JP", "zh_CN"]
for localeId in localeIds {
    formatter.locale = Locale(identifier: localeId)
    print("\(localeId): \(formatter.string(from: interval))")
}

// Локализација за временске интервале
formatter.dateStyle = .none
formatter.timeStyle = .short

let todayStart = Date()
let todayEnd = Date().addingTimeInterval(3600)
let timeInterval = DateInterval(start: todayStart, end: todayEnd)

for localeId in ["ru_RU", "en_US", "de_DE"] {
    formatter.locale = Locale(identifier: localeId)
    print("\(localeId) време: \(formatter.string(from: timeInterval))")
}

Карактеристике локализације: за српски језик DateIntervalFormatter користи предлоге „од“ и „до“ за дугачке формате датума. За кратак (short) формат — само цртица: 21.07–25.07.2024. За пуни формат (full) — са навођењем дана у недељи. Избор формата зависи од контекста: за листу резервација користите .medium, за детаљан преглед — .long или .full.

Поређење са другим форматерима датума

DateIntervalFormatter заузима нишу форматирања опсега датума коју друге класе Foundation-а не покривају. DateFormatter форматира појединачне датуме, RelativeDateTimeFormatter — односне датуме (пре/за), DateComponentsFormatter — трајање (2 сата 30 минута). Свака од ових класа решава сопствени задатак и не могу се замењивати.

КласаНаменаПример излаза
DateIntervalFormatterОпсег датума21–25. јул 2024.
DateFormatterПојединачни датум21. јул 2024.
RelativeDateTimeFormatterОдносно времеПре 3 дана
DateComponentsFormatterТрајање2 сата 30 минута
ISO8601DateFormatterISO 8601 формат2024-07-21T14:30:00Z

Када користити DateIntervalFormatter: за приказ опсега датума у UI-ју — резервација хотела, догађаја, филтрирање по датумима, историја операција. За рачунање трајања између датума користите DateComponentsFormatter, а не DateIntervalFormatter — други није намењен за приказ трајања. DateFormatter користите само за појединачне датуме, а не за лепљење две форматиране датума путем конкатенације низа — то доводи до губитка локализације сепаратора.

Гранични случај: DateIntervalFormatter не подржава приказ отворених опсега (без крајњег датума). Ако је крај опсега непознат (на пример, „од 21. јула“), користите DateFormatter са предлогом „од“ за српски или „from“ за енглески. DateIntervalFormatter такође не подржава опсеге са наводом времена за различите дане — време се примењује на сваки датум посебно, што може изгледати сувишно за кратке опсеге.

Често постављана питања

Шта је DateIntervalFormatter?

DateIntervalFormatter — класа Foundation за форматирање опсега датума у локализоване низове. Доступна од iOS 8, аутоматски групише компоненте које се понављају (месец, година) и бира прави сепаратор за језик.

Како DateIntervalFormatter групише датуме?

Пореди компоненте од године ка дану. Ако се година поклапа — приказује се једном. Ако се месец поклапа — приказује се једном. Различити дани се приказују као опсег. То даје „21–25. јул 2024.“ уместо „21. јул 2024. – 25. јул 2024.“

Могу ли да променим сепаратор опсега?

Не, сепаратор је одређен locale-ом и не може се подесити кроз API. За прилагођен сепаратор (на пример, „до“ уместо „–“), форматирајте сваки датум посебним DateFormatter-ом и лепите низове ручно.

По чему се DateIntervalFormatter разликује од DateFormatter-а?

DateIntervalFormatter форматира опсег датума (два датума) као једну целину са груписањем компонената. DateFormatter форматира један датум. За опсеге увек користите DateIntervalFormatter — то осигурава исправну локализацију сепаратора.

Како форматирати опсег са различитим годинама?

Аутоматски — DateIntervalFormatter открива да су године различите и приказује пуне датуме за оба краја: „25. децембар 2024. – 5. јануар 2025.“. Никаква додатна подешавања нису потребна, довољно је поставити dateStyle.

Резиме

  • DateIntervalFormatter — специјализована класа за форматирање опсега датума (iOS 8+)
  • Аутоматско груписање — компоненте које се понављају (година, месец) приказују се једном за цео опсег
  • Локализовани сепаратори — „од–до“ (српски), цртица (енглески), „bis“ (немачки) — аутоматски
  • Стилови датума и времена — комбинације .none, .short, .medium, .long, .full за сваки крај опсега
  • Није погодан за трајање — за рачунање трајања користите DateComponentsFormatter
  • Не подржава прилагођене сепараторе — за нестандардне случајеве потребно је ручно форматирање
  • Интеграција са DateInterval — структура DateInterval пружа провере contains и intersection

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође