Acho que um dos assuntos que mais causa confusão, depois talvez de goroutines e channels, é a manipulação de datas em Go.
Nesse post vou mostrar como manipular, comparar, formatar e fazer parse de datas em Go.
Para iniciar, vamos “printar” a data atual da forma mais simples possível.
package main import ( "fmt" "time" ) func main() { now := time.Now() fmt.Println(now) }
Ao executar nosso código, veremos um output parecido com 2022-04-27 05:43:52.821666 -0300 -03 m=+0.00011210
, que é formado por:
- 2022-04-27 – ano-mês-dia
- 05:43:52.821666 – hora:minuto:segundo.nano segundo
- -03 – timezone
- m=+0.00011210 – Monotonic clock
Formatando
Ok, agora que entendemos os componentes da data, vamos fazer uma formatação para exibir de uma forma mais humana e nos padrões que costumamos utilizar no Brasil.
fmt.Println(now.Format("02/01/2006 03:04:05"))
Agora, ao executar nosso código novamente teremos um output parecido com 27/04/2022 05:53:04
.
Nesse ponto, provavelmente você está se perguntando de onde eu tirei esses valores que coloquei dentro do método Format.
Diferente da maioria das outras linguagens, Go oferece uma “sequência” de “1 até 7” como parâmetros para formatação da datas, onde:
- 01 ou 1 = mês
- 02 ou 2 = dia
- 03 ou 3 = hora (você também pode usar 15 para representar 24h)
- 04 ou 4 = minuto
- 05 ou 5 = segundo
- 06 = ano (2006 para exibir com 4 dígitos)
- -07 ou -0700 = timezone
Voltando agora para a struct time.Time
, que é a struct retornada pela função time.Now()
, além do método Format que acabamos de ver, essa struct tem um método para cada uma das partes da data.
fmt.Println("dia: ", now.Day()) fmt.Println("mês: ", now.Month()) fmt.Println("ano: ", now.Year()) fmt.Println("hora: ", now.Hour()) fmt.Println("minuto: ", now.Minute()) fmt.Println("segundo: ", now.Second()) tz, _ := now.Zone() fmt.Println("timezone: ", tz)
Criando manualmente e fazendo Parse
Uma das formas para criar uma data manualmente, é utilizar a função time.Date
com os parâmetros “ano”, “mês”, “dia”, “hora”, “minuto”, “segundo”, “nano segundo”, “timezone”.
manual := time.Date(2022, 05, 10, 06, 15, 30, 100, time.Local) fmt.Println(manual) //output: 2022-05-10 06:15:30.0000001 -0300 -03
Outra forma seria fazer o parse de uma string.
tstr := "27/04/2022 07:34:45" parsed, err := time.Parse("02/01/2006 03:04:05", tstr) if err != nil { log.Fatal(err) } fmt.Println(parsed) // output: 2022-04-27 07:34:45 +0000 UTC
No entanto, reparem no output. Se a data realmente estiver sendo salva em UTC, então não temos problemas. Agora, se a data for referente a nossa timezone por exemplo, então a data exibida está “incorreta”.
Para corrigir esse problema, precisamos adicionar a timezone na string e o código de parse da timezone no parâmetro “formato” do método Parse.
tstr := "27/04/2022 07:34:45 -03" parsed, err := time.Parse("02/01/2006 03:04:05 -07", tstr) if err != nil { log.Fatal(err) } fmt.Println(parsed) // output: 2022-04-27 07:34:45 -0300 -03
Manipulando e comparando
Para incrementar ou decrementar uma data, existem duas formas básicas para se fazer. A primeira consiste em criar uma nova data utilizando todas as informações da data anterior e incrementar/decrementar o valor (dia, mês, ano e etc..).
now := time.Now() // adiciona 13 dias manual := time.Date(now.Year(), now.Month(), now.Day()+13, now.Hour(), now.Minute(), now.Second(), now.Nanosecond(), now.Location()) fmt.Println(manual)
A segunda forma é utilizar o método Add da struct time.Time
.
now := time.Now() // adicionar 13 dias next := now.Add(13 * 24 * time.Hour) fmt.Println(next)
Mas será que as duas datas ficaram iguais mesmo? Para descobrir isso, vamos utilizar o método Equal da struct time.Time
.
now := time.Now() next := now.Add(13 * 24 * time.Hour) fmt.Println(next) manual := time.Date(now.Year(), now.Month(), now.Day()+13, now.Hour(), now.Minute(), now.Second(), now.Nanosecond(), now.Location()) fmt.Println(manual) fmt.Println(next.Equal(manual)) // output: // 2022-05-10 06:25:04.389426 -0300 -03 m=+1123200.000084928 // 2022-05-10 06:25:04.389426 -0300 -03 // true
Além do método Equal, a struct time.Time
também oferece os métodos Before (para ver se a data é anterior) e After (para ver se a data é posterior).
Os três métodos recebem somente um parâmetro, que é a data com o qual a comparação está sendo feita.
Espero que tenham gostado.
Deixem suas dúvidas nos comentários.
Até a próxima!