DateIntervalFormatter — conceitos básicos de formatação de intervalos de data

Autor: IT Sectr Publicado: 2026-07-13 Tempo de leitura: 11 min

DateIntervalFormatter é uma classe Foundation no iOS e macOS projetada para formatar intervalos de datas em strings localizadas: “21–25 de julho de 2024”, “de 21 a 25 de julho de 2024” ou “Jul 21–25, 2024”. De acordo com Apple Developer Documentation, 2024, o DateIntervalFormatter determina automaticamente quais componentes de data repetir (se o intervalo estiver dentro de um mês, o mês é exibido uma vez) e localiza os separadores e a ordem das palavras. Ao contrário da concatenação manual de duas datas formatadas, esta classe leva em conta as regras gramaticais do idioma. A classe está disponível desde o iOS 8 e macOS 10.10.

Pontos principais

  • DateIntervalFormatter — classe Foundation para formatar intervalos de datas (iOS 8+)
  • Agrupamento automático — componentes repetidos (mês, ano) são exibidos uma vez
  • Separadores localizados — regras gramaticais: “a” (português), travessão (inglês)
  • Cinco estilos de data — .none, .short, .medium, .long, .full para cada extremidade do intervalo
  • Quatro estilos de hora — mesmos níveis de detalhe para a parte horária do intervalo

O que é DateIntervalFormatter?

DateIntervalFormatter é uma subclasse de Formatter no Foundation que recebe um objeto DateInterval (um intervalo entre duas datas) e retorna uma string localizada descrevendo esse intervalo. Por exemplo, para o intervalo de 21 a 25 de julho de 2024, o resultado seria “21–25 de julho de 2024” para pt_BR. A classe agrupa inteligentemente elementos repetidos: se ambas as datas estiverem no mesmo mês, o nome do mês é exibido uma vez.

O principal valor do DateIntervalFormatter é o tratamento automático da gramática de intervalos. Ao formatar manualmente, um desenvolvedor teria que comparar mês/ano de início e fim, escolher um separador (travessão, “a”, “bis”) e lidar com a declinação. O DateIntervalFormatter faz isso automaticamente com base nos dados do CLDR (Common Locale Data Repository), reduzindo erros em aplicações internacionais, especialmente para idiomas com gramática complexa.

De acordo com Unicode CLDR v44 (2024), as regras de formatação de intervalos de data variam significativamente entre os idiomas. O alemão usa a preposição “bis” (21.–25. Juli 2024), o francês usa “au” (du 21 au 25 juillet 2024), o japonês usa um hífen (2024 Jul 21–25). O DateIntervalFormatter cobre todas essas variações sem código adicional do desenvolvedor.

Como funciona o DateIntervalFormatter no Foundation?

O princípio de funcionamento do DateIntervalFormatter é baseado na análise de duas datas formando um intervalo e na seleção da representação textual ideal considerando a localidade. A classe compara os componentes de data (ano, mês, dia) e toma decisões de agrupamento: se o ano é o mesmo, é exibido uma vez; se o mês é o mesmo, é exibido uma vez; se os dias diferem, um intervalo de dias é exibido.

Intervalopt_BR
Um dia21 de julho de 2024
Dentro do mês21–25 de julho de 2024
Meses diferentes21 de julho – 5 de agosto de 2024
Anos diferentes25 de dezembro de 2024 – 5 de janeiro de 2025
Com hora21 de julho de 2024, 14:30–16:45

Lógica de agrupamento implementada com base em templates CLDR. O formatador verifica a igualdade de cada componente de data (Calendar.Component: year, month, day) na ordem do maior para o menor. Uma vez que um componente difere, todos os componentes menores são exibidos para ambas as datas. Por exemplo, para 21–25 de julho: ano corresponde, mês corresponde, dia difere → mês é exibido uma vez, dias são exibidos para cada data.

Nota importante: DateIntervalFormatter não suporta personalização do separador via API. O separador é determinado pela localidade e não pode ser sobrescrito. Se for necessário um separador não padrão (por exemplo, “até” em vez de “a”), você precisará formatar as datas manualmente usando DateFormatter e concatenar as strings com um separador personalizado.

Estilos de formatação de intervalos

DateIntervalFormatter fornece dois conjuntos de estilos: dateStyle e timeStyle para cada extremidade do intervalo. Esses estilos funcionam de forma semelhante ao DateFormatter: .none oculta o componente, .short dá um formato curto (21/07/2024), .medium (21 jul 2024), .long (21 de julho de 2024), .full (domingo, 21 de julho de 2024). Combinando dateStyle e timeStyle, diferentes níveis de detalhe podem ser alcançados.

Exemplos de combinações de estilos

  • dateStyle = .medium, timeStyle = .none — apenas data: “21–25 de julho de 2024”
  • dateStyle = .short, timeStyle = .short — data e hora: “21/07/2024, 14:30 – 25/07/2024, 16:45”
  • dateStyle = .none, timeStyle = .short — apenas hora: “14:30–16:45” (se as datas forem iguais)
  • dateStyle = .long, timeStyle = .none — data longa: “21–25 de julho de 2024”
  • dateStyle = .full, timeStyle = .short — formato completo: “domingo, 21 de julho de 2024 – quinta-feira, 25 de julho de 2024”

Importante: dateStyle e timeStyle se aplicam a ambas as extremidades do intervalo igualmente. Não é possível definir estilos diferentes para o início e o fim (por exemplo, .medium para o início e .short para o fim). Se forem necessários estilos diferentes, você deve formatar cada data com um DateFormatter separado e concatenar os resultados.

swift
import Foundation

let formatter = DateIntervalFormatter()

// Combinações de estilos diferentes
let startDate = Date()
let endDate = Date().addingTimeInterval(345600) // +4 dias
let interval = DateInterval(start: startDate, end: endDate)

// Apenas data, formato médio
formatter.dateStyle = .medium
formatter.timeStyle = .none
print("Apenas data: \(formatter.string(from: interval))")

// Formato curto com hora
formatter.dateStyle = .short
formatter.timeStyle = .short
print("Curto com hora: \(formatter.string(from: interval))")

// Formato completo
formatter.dateStyle = .full
formatter.timeStyle = .none
print("Data completa: \(formatter.string(from: interval))")

DateIntervalFormatter em Swift: exemplos

Uso básico do DateIntervalFormatter inclui criar uma instância, definir estilos e chamar string(from:). O método aceita DateInterval, uma estrutura com propriedades start e end. DateInterval pode ser criado a partir de dois valores Date ou inicializado com Duration (iOS 16+). Após a formatação, o resultado está pronto para exibição na interface sem processamento adicional.

swift
import Foundation

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

// Exemplos de intervalos específicos
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)")
}

// Formatar via Calendar (iOS 16+)
if let nextWeek = calendar.date(
    byAdding: .day, value: 7, to: now
) {
    let weekInterval = DateInterval(start: now, end: nextWeek)
    print("Próximos 7 dias: \(intervalFormatter.string(from: weekInterval))")
}

DateIntervalFormatter e reservas de calendário: em aplicações de reserva (hotéis, bilhetes), os intervalos de data são um elemento chave da interface. DateIntervalFormatter lida corretamente com intervalos entre anos (por exemplo, 28 de dezembro a 3 de janeiro), agrupando mês e ano para cada data separadamente. Para tais cenários, recomenda-se usar dateStyle = .medium e timeStyle = .none, o formato mais legível para datas sem hora.

swift
import Foundation

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

// Exemplos de reservas
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("Reserva: \(booking.formattedInterval)")

// Usar com diferentes localidades
let enFormatter = DateIntervalFormatter()
enFormatter.dateStyle = .medium
enFormatter.timeStyle = .none
enFormatter.locale = Locale(identifier: "en_US")
print("Inglês: \(enFormatter.string(from: interval))")

DateInterval vs DateIntervalFormatter: DateInterval é uma estrutura que representa um intervalo de datas (início e fim). DateIntervalFormatter é um formatador que converte esta estrutura em uma string. DateInterval também suporta verificação contains(Date) e intersection(with:), útil para lógica de reservas (verificar sobreposição de datas).

Localização de intervalos de data

DateIntervalFormatter localiza a saída através da propriedade locale. Por padrão, Locale.current é usado, a localidade do dispositivo. Para exibir intervalos em outro idioma (por exemplo, conteúdo em inglês com interface em português), defina a locale explicitamente. Ao contrário do DateFormatter, DateIntervalFormatter não requer definição de locale para dados do servidor. Ele sempre usa sua lógica de agrupamento interna baseada em CLDR.

As diferenças idiomáticas na formatação de intervalos de data são significativamente mais complexas do que para datas individuais. O português usa a preposição “a”: de 21 a 25 de julho. O inglês usa um travessão simples: Jul 21–25. O francês usa a preposição “au”: du 21 au 25 juillet. O alemão usa um ponto após o número e um travessão: 21.–25. Juli. DateIntervalFormatter cobre todas essas variantes.

swift
import Foundation

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

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

// Demonstrar diferentes localidades
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))")
}

// Localização para intervalos de tempo
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) hora: \(formatter.string(from: timeInterval))")
}

Particularidades de localização: para português, DateIntervalFormatter usa a preposição “a” para formatos longos. Para formatos curtos, usa o travessão. A escolha do formato depende do contexto: para uma lista de reservas use .medium, para visualização detalhada use .long ou .full.

Comparação com outros formatadores de data

DateIntervalFormatter preenche o nicho de formatação de intervalos de datas, que não é coberto por outras classes Foundation. DateFormatter formata datas individuais, RelativeDateTimeFormatter formata datas relativas (atrás/em), DateComponentsFormatter formata duração (2 horas 30 minutos). Cada uma dessas classes resolve uma tarefa específica e não podem ser usadas indistintamente.

ClassePropósitoExemplo de saída
DateIntervalFormatterIntervalo de datas21–25 de julho de 2024
DateFormatterData individual21 de julho de 2024
RelativeDateTimeFormatterTempo relativohá 3 dias
DateComponentsFormatterDuração2 horas 30 minutos
ISO8601DateFormatterFormato ISO 86012024-07-21T14:30:00Z

Quando usar DateIntervalFormatter: para exibir intervalos de datas na interface — reservas de hotéis, eventos, filtragem por datas, histórico de operações. Para calcular a duração entre datas, use DateComponentsFormatter, não DateIntervalFormatter, pois este último não foi projetado para exibir duração. DateFormatter deve ser usado apenas para datas individuais, não para concatenar duas datas formatadas via concatenação de strings, pois isso leva à perda de localização do separador.

Caso extremo: DateIntervalFormatter não suporta exibição de intervalos abertos (sem data de término). Se o fim do intervalo for desconhecido (por exemplo, “desde 21 de julho”), use DateFormatter com a preposição “desde”. Além disso, DateIntervalFormatter não suporta intervalos com hora especificada para dias diferentes. A hora é aplicada a cada data separadamente, o que pode parecer redundante para intervalos curtos.

Perguntas frequentes

O que é DateIntervalFormatter?

DateIntervalFormatter é uma classe Foundation para formatar intervalos de datas em strings localizadas. Disponível desde iOS 8, agrupa automaticamente componentes repetidos (mês, ano) e seleciona o separador correto para o idioma.

Como DateIntervalFormatter agrupa datas?

Ele compara componentes do ano ao dia. Se o ano corresponder, é exibido uma vez. Se o mês corresponder, é exibido uma vez. Dias diferentes são exibidos como um intervalo. Isso dá “21–25 de julho de 2024” em vez de “21 de julho de 2024 – 25 de julho de 2024”.

Posso alterar o separador do intervalo?

Não, o separador é determinado pela localidade e não pode ser personalizado via API. Para um separador personalizado (por exemplo, “até” em vez de “a”), formate cada data com um DateFormatter separado e concatene as strings manualmente.

Como DateIntervalFormatter difere de DateFormatter?

DateIntervalFormatter formata um intervalo de datas (duas datas) como uma unidade única com agrupamento de componentes. DateFormatter formata uma data individual. Para intervalos, use sempre DateIntervalFormatter, pois ele fornece a localização correta do separador.

Como formatar um intervalo com anos diferentes?

Automaticamente — DateIntervalFormatter detecta que os anos diferem e exibe as datas completas para ambas as extremidades: “25 de dezembro de 2024 – 5 de janeiro de 2025”. Nenhuma configuração adicional é necessária, basta definir o dateStyle.

Resumo

  • DateIntervalFormatter — classe especializada para formatar intervalos de datas (iOS 8+)
  • Agrupamento automático — componentes repetidos (ano, mês) são exibidos uma vez para todo o intervalo
  • Separadores localizados — “a” (português), “bis” (alemão) automaticamente
  • Estilos de data e hora — combinações de .none, .short, .medium, .long, .full para cada extremidade do intervalo
  • Não para duração — para calcular duração use DateComponentsFormatter
  • Sem separadores personalizados — para casos não padrão é necessária formatação manual
  • Integração com DateInterval — a estrutura DateInterval fornece verificações contains e intersection

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também