Tempo não são apenas números: por que até desenvolvedores experientes erram
\n\nTodo desenvolvedor iOS já enfrentou a tarefa: "só preciso obter a hora atual". Parece simples, não é? Mas é exatamente aqui, do nada, que iniciantes (e não só) cometem erros que depois viram bugs, travamentos de aplicativos e usuários insatisfeitos.
\n\nNeste artigo, vamos analisar cinco dos erros mais comuns ao trabalhar com a hora atual em Swift, que acumularam milhares de visualizações no Stack Overflow. Você aprenderá como evitá-los e escrever código limpo e confiável.
\n\n"Eu só quero obter a hora atual como datetime em Swift, mas recebo nil ou algo que não esperava. Ajuda!" — um típico desabafo em fóruns.\n\n
Vamos entender o que está dando errado.
\n\n1. Erro com DateFormatter: a localidade é a principal inimiga
\n\nProblema
\nA consulta mais popular: "Swift get current time as datetime string". O desenvolvedor escreve:
\n\nlet dateFormatter = DateFormatter()\ndateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"\nlet currentTime = dateFormatter.string(from: Date())\nprint(currentTime) // Funciona? Nem sempre\n\nNo simulador ou em um dispositivo com localidade inglesa, tudo funciona perfeitamente. Mas quando o usuário seleciona, por exemplo, alemão ou russo nas configurações — você recebe nil ou um formato inesperado.
Por que isso acontece?
\nPor padrão, o DateFormatter usa a localidade atual do dispositivo. Para formatos de data fixos, que são analisados ou exibidos em APIs, isso é um desastre.
Solução
\nSempre defina a localidade en_US_POSIX para formatos que não são destinados à exibição para o usuário:
let dateFormatter = DateFormatter()\ndateFormatter.locale = Locale(identifier: "en_US_POSIX")\ndateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"\ndateFormatter.timeZone = TimeZone.current // Não esqueça do fuso horário!\nlet currentTime = dateFormatter.string(from: Date())\nprint(currentTime) // "2024-12-25 14:30:00" — estável\n\nLembre-se: en_US_POSIX é seu melhor amigo ao trabalhar com formatos de data fixos em Swift.\n\n
2. Ignorar o fuso horário (TimeZone)
\n\nProblema
\nVocê obteve uma string com a hora atual. Mas que hora você realmente obteve? Local? UTC? Do servidor? O erro ocorre quando o desenvolvedor não define timeZone no DateFormatter.
Exemplo de erro:
\nlet formatter = DateFormatter()\nformatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"\nlet now = formatter.string(from: Date())\n// Resultado: "2024-12-25T14:30:00+0300" — hora local com offset\n// Mas e se você precisar sempre de UTC?\n\nSolução
\nSempre especifique explicitamente o TimeZone:
\n\n// Para trabalhar com servidor (UTC)\nlet utcFormatter = DateFormatter()\nutcFormatter.timeZone = TimeZone(abbreviation: "UTC")\nutcFormatter.locale = Locale(identifier: "en_US_POSIX")\nutcFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'"\nlet utcTime = utcFormatter.string(from: Date())\nprint(utcTime) // "2024-12-25T11:30:00Z"\n\n// Para exibir ao usuário (hora local dele)\nlet localFormatter = DateFormatter()\nlocalFormatter.timeZone = TimeZone.current\nlocalFormatter.dateStyle = .medium\nlocalFormatter.timeStyle = .short\nlet localTime = localFormatter.string(from: Date())\nprint(localTime) // "25 de dez. de 2024, 14:30"\n\n3. Usar Date() para comparação: armadilhas ocultas
\n\nProblema
\nMuitos pensam que Date() retorna o mesmo valor dentro de uma única chamada. Mas não é verdade. Swift Date é um instantâneo do tempo. Se você chamar Date() duas vezes no código, os valores podem diferir por microssegundos.
Blogs
Book Recommendations
Leia também