Introdução ao trabalho com datas e horas em Go
Trabalhar com datas e horas é uma das tarefas essenciais em qualquer aplicação séria. Seja para registro de eventos, cálculo de timeouts, trabalho com agendamentos ou análise de séries temporais, a linguagem Go fornece um conjunto de ferramentas poderoso e elegante no pacote padrão time. Neste artigo, abordaremos o trabalho com datas e horas em Go de A a Z: desde a criação de objetos de tempo até operações complexas com fusos horários e temporizadores.
Fundamentos: a estrutura time.Time e criação de datas
O elemento central do pacote time é a estrutura time.Time. Ela representa um momento no tempo com precisão de nanossegundos e informações sobre o fuso horário.
Obtendo a hora atual
O cenário mais comum é obter o momento atual:
package main
import ( "fmt" "time")
func main() { now := time.Now() fmt.Println("Hora atual:", now)}Criando uma data específica
Para criar uma data, usa-se a função time.Date(). Observe: em Go, os meses são definidos por constantes (time.January, time.February, etc.) ou por números de 1 a 12.
func main() { // 15 de março de 2025, 14:30:00, UTC specificDate := time.Date(2025, time.March, 15, 14, 30, 0, 0, time.UTC) fmt.Println("Data específica:", specificDate) // Criando com nanossegundos preciseDate := time.Date(2025, 3, 15, 14, 30, 0, 123456789, time.UTC) fmt.Println("Data precisa:", preciseDate)}Formatação e análise de datas
Em Go, usa-se uma abordagem única para formatação: em vez de códigos como %Y-%m-%d, você usa o tempo de referência Mon Jan 2 15:04:05 MST 2006 (que se lê como 01 02 03 04 05 06 07 — ano, mês, dia, hora, minuto, segundo, ano).
Formatação (time → string)
O método Format() converte o tempo em uma string de acordo com o padrão fornecido:
func main() { now := time.Now() // Formatos padrão fmt.Println("RFC3339:", now.Format(time.RFC3339)) fmt.Println("Data:", now.Format("2006-01-02")) fmt.Println("Hora:", now.Format("15:04:05")) fmt.Println("Formato completo:", now.Format("02.01.2006 15:04:05")) fmt.Println("Com dia da semana:", now.Format("Mon, 02 Jan 2006"))}Análise (string → time.Time)
A função time.Parse() analisa uma string em uma estrutura de tempo. Importante: o padrão deve corresponder exatamente ao formato da string de entrada.
func main() { // Análise com formato conhecido dateStr := "2025-03-15 14:30:00" parsed, err := time.Parse("2006-01-02 15:04:05", dateStr) if err != nil { panic(err) } fmt.Println("Analisado:", parsed) // Análise com fuso horário dateWithZone := "2025-03-15T14:30:00+03:00" parsedWithZone, _ := time.Parse(time.RFC3339, dateWithZone) fmt.Println("Com fuso horário:", parsedWithZone)}Aritmética de tempo: intervalos e comparações
O pacote time fornece o tipo Duration para representar intervalos de tempo e métodos para operações aritméticas.
Adição e subtração
func main() { now := time.Now() // Adicionando 2 horas e 30 minutos future := now.Add(2*time.Hour + 30*time.Minute) fmt.Println("Daqui a 2.5 horas:", future) // Subtraindo 7 dias past := now.Add(-7 * 24 * time.Hour) fmt.Println("Uma semana atrás:", past) // Usando AddDate para trabalhar com datas do calendário nextMonth := now.AddDate(0, 1, 0) fmt.Println("Daqui a um mês:", nextMonth)}Calculando a diferença entre datas
O método Sub() retorna um Duration:
func main() { start := time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC) end