Trabalho com datas e horas em Swift: técnicas avançadas

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Trabalho Avançado com Datas e Horas em Swift: do básico à otimização

\n

Trabalhar com datas e horas é uma das tarefas mais comuns e, ao mesmo tempo, traiçoeiras no desenvolvimento iOS/macOS. A aparente simplicidade da API Foundation (Date, DateFormatter, Calendar) frequentemente leva a erros relacionados a fusos horários, localização ou desempenho. Neste artigo, vamos explorar técnicas avançadas de trabalho com datas em Swift: desde parsing adequado até cálculos de alto desempenho que serão úteis em projetos de produção.

\n\n

1. DateFormatter: ajuste fino e cache

\n

O erro mais comum de iniciantes é criar um novo objeto DateFormatter dentro de um loop ou método chamado com frequência. Criar um DateFormatter é uma operação cara (até 1000 vezes mais lenta do que reutilizá-lo).

\n\n
// ❌ Ruim: criamos um formatter toda vez\nfunc parseDate(from string: String) -> Date? {\n    let formatter = DateFormatter()\n    formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"\n    formatter.locale = Locale(identifier: "ru_RU")\n    formatter.timeZone = TimeZone(secondsFromGMT: 0)\n    return formatter.date(from: string)\n}\n\n// ✅ Bom: fazemos cache do formatter\nprivate let isoDateFormatter: DateFormatter = {\n    let f = DateFormatter()\n    f.dateFormat = "yyyy-MM-dd HH:mm:ss"\n    f.locale = Locale(identifier: "ru_RU")\n    f.timeZone = TimeZone(secondsFromGMT: 0)\n    return f\n}()\n\nfunc parseDateFast(from string: String) -> Date? {\n    return isoDateFormatter.date(from: string)\n}
\n\n

Dica avançada: Para trabalhar com formatos fixos (como ISO 8601), use ISO8601DateFormatter — ele é mais rápido que o DateFormatter padrão. Para formatos personalizados que exigem alto desempenho, considere DateFormatter com armazenamento thread-local:

\n\n
extension DateFormatter {\n    static let threadLocal: ThreadLocal<DateFormatter> = ThreadLocal {\n        let f = DateFormatter()\n        f.dateFormat = "dd.MM.yyyy"\n        f.locale = Locale(identifier: "ru_RU")\n        return f\n    }\n}
\n\n

2. Calendar e DateComponents: cálculos sem erros

\n

Para aritmética com datas (adicionar um dia, encontrar o início do mês), use Calendar, em vez de somar segundos manualmente. Adicionar manualmente 86400 segundos (24*60*60) quebra durante a mudança para o horário de verão.

\n\n
let calendar = Calendar.current\nlet now = Date()\n\n// ✅ Adicionamos 1 dia com segurança\nif let tomorrow = calendar.date(byAdding: .day, value: 1, to: now) {\n    print("Amanhã: \\(tomorrow)")\n}\n\n// ✅ Encontramos o início do mês atual\nlet startOfMonth = calendar.date(from: calendar.dateComponents([.year, .month], from: now))!\n\n// ✅ Obtemos componentes considerando a localidade\nlet components = calendar.dateComponents([.weekday, .weekOfYear], from: now)\nprint("Dia da semana: \\(components.weekday ?? 0)") // 1 = domingo nos EUA, 2 = segunda-feira no Brasil
\n\n

Dica avançada: Para cálculos de alta carga (como gerar uma grade de calendário), faça cache de Calendar e TimeZone. Evite usar Calendar.current em loops — ele acessa as configurações do sistema a cada vez.

\n\n

3. Localização e formatação para o usuário

\n

Nunca mostre uma data bruta ao usuário. Use DateFormatter com estilos predefinidos (.short, .medium, .long, .full) e RelativeDateTimeFormatter para datas relativas legíveis ("ontem", "3 dias atrás").

\n\n
// Data absoluta considerando a localidade do usuário\nlet userFormatter = DateFormatter()\nuserFormatter.dateStyle = .long\nuserFormatter.timeStyle = .short\nprint(userFormatter.string(from: Date())) // "15 de junho de 2025 às 14:30" (para pt_BR)\n\n// Data relativa (iOS 13+)\nlet relativeFormatter = RelativeDateTimeFormatter()\nrelat                

Blogs

Book Recommendations