"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Como lidar com fusos horários e sincronizar seu software no lado do servidor usando Go

Como lidar com fusos horários e sincronizar seu software no lado do servidor usando Go

Publicado em 2024-11-03
Navegar:630

Quando seu aplicativo for iniciado em grande escala, o aumento de usuários aumentará. O que é muito provável que aconteça é que a localização do usuário não esteja apenas na mesma área, mas também em outra área com fuso horário diferente. Portanto, como desenvolvedor de back-end, é muito importante pensar em coisas relacionadas ao tratamento de diferenças de fuso horário.

Recentemente me deparei com um problema envolvendo fusos horários. Sejamos honestos, lidar com datas e horários é uma das áreas mais complicadas que um ser humano tem de lidar. E esta foi uma oportunidade para aprender como lidar adequadamente com datas e horas no lado do servidor.

Neste artigo, compartilharei minha experiência sobre como lidar com diferenças de fuso horário no lado do servidor como desenvolvedor back-end. Talvez se alguém estiver disposto a corrigir e fornecer informações adicionais, isso seria valioso para mim.

Sobre o fuso horário

Os fusos horários são um sistema de divisão de tempo padrão usado em todo o mundo para organizar e padronizar a medição do tempo. Este conceito surgiu como uma resposta à necessidade de coordenação global do tempo, especialmente junto com os desenvolvimentos na tecnologia de comunicações e transporte.

O princípio básico dos fusos horários é a divisão da Terra em 24 zonas. Cada fuso horário é geralmente uma hora diferente do fuso próximo a ele. A principal referência para fusos horários é o Tempo Médio de Greenwich (GMT) ou Tempo Universal Coordenado (UTC), que está na linha de longitude zero grau que passa por Greenwich, Inglaterra.

How to Handle Time Zones and Sync Your Software on the server side using Go
Ilustração de Hellerick do Wikimedia Commons

Um pequeno exemplo é quando o relógio marca 12h00 em Jacarta, em Nova York o horário marca 00h00 ou meia-noite. Isso significa que enquanto os habitantes de Jacarta desfrutam do almoço, os nova-iorquinos estão apenas começando o novo dia. A partir daqui você certamente pode imaginar a importância de lidar corretamente com os fusos horários na construção de um aplicativo.

Tratamento de fuso horário no lado do servidor

Depois de vermos a explicação acima, agora entraremos nos pontos que podem ser feitos quando nossa aplicação servidora recebe uma solicitação de um cliente que acessa nossa API para lidar com seu fuso horário.

Neste artigo, discutirei várias abordagens para lidar com fusos horários no lado do servidor. Aqui usarei exemplos de código na linguagem Golang (Go). Golang possui um pacote de tempo para trabalhar com dados relacionados ao tempo que é considerado bastante completo. Aqui estão alguns pontos que discutiremos:

  • Como salvar data no banco de dados
  • Conversão da hora local do usuário
  • Teste e validação

Como salvar data no banco de dados

A primeira coisa que vamos discutir é qual tempo vamos economizar no banco de dados, por exemplo temos uma aplicação de ecommerce que faz vendas flash, onde nossa aplicação já está em escala internacional.

Quando um usuário processa uma transação de compra na América ou se estiver na Indonésia, o usuário enviará seu horário local diferente para o servidor. A questão é: nosso banco de dados armazenará dados de horário de acordo com a hora local do usuário? Se a resposta for sim, provavelmente é um problema complicado quando queremos recuperar os dados ou, por exemplo, o administrador deseja fazer o processamento de dados, qual usuário faz a transação mais antiga.

Para superar isso, a prática recomendada é armazenar os tempos de transação no fuso horário UTC (Tempo Universal Coordenado), que é o principal padrão de horário para relógios e configurações de horário. Aqui está a aplicação do horário ao UTC.

package main

import (
    "fmt"
    "time"
)

func main() {

    now := time.Now()
    fmt.Printf("Local time: %s\n", now)

    nowInUTC := now.UTC()
    fmt.Printf("UTC time: %s\n", nowInUTC)

}

Vamos ver o significado do código acima.

Primeiro, na linha de código now := time.Now(), esta linha usa a função Now() do pacote time para obter a hora atual com base no fuso horário local do sistema. O resultado é armazenado na variável atual.

Então, na linha nowInUTC := now.UTC(), aqui convertemos a hora local (now) para a hora UTC usando o método UTC(). Os resultados são armazenados em uma nova variável nowInUTC e desta vez podem ser armazenados no servidor, onde se espera que os desenvolvedores possam evitar ambiguidades e erros que podem surgir devido a diferenças de fuso horário entre servidores e usuários em várias regiões com fusos horários diferentes.

Aqui estão os resultados se executarmos o código acima:

How to Handle Time Zones and Sync Your Software on the server side using Go

Mas esta nem sempre é a melhor solução que você deve usar. Pode haver alguns pontos que você deve ter em mente em determinados casos de uso. Um deles é: é verdade que nossos usuários vêm de fusos horários diferentes? Se não for possível, talvez armazenar a hora em UTC adicione complexidade ao seu código.

Alterar a hora para a localidade do usuário

No ponto de discussão acima, concordamos em armazenar os dados de horário do usuário em um local, ou seja, UTC. Agora, como os usuários podem ver a hora precisa de acordo com sua localização. Um exemplo da discussão acima é uma venda relâmpago em um aplicativo de comércio eletrônico que temos, onde os usuários também desejam saber informações sobre qual usuário fez a primeira transação. Portanto, neste ponto, converter o horário que armazenamos no banco de dados para o horário local do usuário é outra coisa importante que não devemos ignorar.

A abordagem que adoto é que o lado do servidor sempre pede ao cliente para enviar o fuso horário do lado do usuário. Isso pode ser feito no lado da solicitação, onde o cliente envia um cabeçalho com o fuso horário da chave e possui o valor do fuso horário do usuário. Por exemplo, a Indonésia tem 3 divisões de fuso horário, nomeadamente WIT( 9), WITA( 8), WIB( 7). Onde cada zona tem uma diferença de 1 hora. Se anteriormente em nosso servidor armazenávamos a hora UTC às 00h00, então no lado WIT era às 09h00, depois no lado WITA era às 08h00 e WIB às 07h00.

Aqui está um exemplo de código para lidar com o caso acima:

package main

import (
    "fmt"
    "time"
)

func ParseTimezoneFromString(tz string) *time.Location {

    if len(tz) > 0 {

        t, err := time.Parse("2006 -07:00", fmt.Sprintf("2007 %s", tz))

        if err != nil {

            panic(err)

        } else {

            return t.Location()
        }
    }

    return time.Now().Location()
}

func main() {

    timeServerInUTC := "2024-08-04 00:00:00"
    nowInUTC, err := time.Parse("2006-01-02 15:04:05", timeServerInUTC)
    if err != nil {
        panic(err)
    }

    fmt.Printf("UTC time: %s\n", nowInUTC)

    witLocation := ParseTimezoneFromString(" 09:00")

    nowInWIT := nowInUTC.In(witLocation)
    fmt.Printf("WIT time: %s\n", nowInWIT)

    witaLocation := ParseTimezoneFromString(" 08:00")

    nowInWITA := nowInUTC.In(witaLocation)
    fmt.Printf("WITA time: %s\n", nowInWITA)

    wibLocation := ParseTimezoneFromString(" 07:00")

    nowInWIB := nowInUTC.In(wibLocation)
    fmt.Printf("WIB time: %s\n", nowInWIB)

}

crédito ao dikac por criar esta função ParseTimezoneFromString

Vamos entender o significado do código acima:

Primeiro, criamos uma função ParseTimezoneFromString, onde esta função é usada para encontrar a localização da hora com base no argumento tz ou fuso horário da localização do usuário fornecida. Se o valor da string tz for válido, converteremos o fuso horário da string usando a função time.Parse para converter a string em um objeto de tempo e, em seguida, extrairemos a localização (fuso horário) desse objeto. E também tratamos se a string estiver vazia ou a análise falhar, a função retorna o fuso horário local do sistema.

func ParseTimezoneFromString(tz string) *time.Location {

    if len(tz) > 0 {

        t, err := time.Parse("2006 -07:00", fmt.Sprintf("2007 %s", tz))

        if err != nil {

            panic(err)

        } else {

            return t.Location()
        }
    }

    return time.Now().Location()
}

Em seguida, também definimos dados de tempo no seguinte formato de string:

timeServerInUTC := "2024-08-04 00:00:00"

nowInUTC, err := time.Parse("2006-01-02 15:04:05", timeServerInUTC)
if err != nil {
    panic(err)
}

Você pode pensar nisso como os dados de tempo que obtemos do servidor. E analise-o em um objeto de tempo.

Em seguida, tentamos encontrar a localização precisa do usuário com base na função ParseTimezoneFromString que criamos anteriormente com base no argumento de string que definimos. O que precisa ser observado é que esse argumento de string é o que significa o valor do cabeçalho do fuso horário enviado pelo cliente por meio da solicitação recebida.

Podemos usar a localização que obtemos da função ParseTimezoneFromString para converter ou mudar a hora que obtemos do servidor para a hora local do usuário. Podemos fazer isso usando a função In que também está incluída no pacote time que podemos ver no seguinte trecho de código:

nowInWIT := nowInUTC.In(witLocation)
nowInWITA := nowInUTC.In(witaLocation)
nowInWIB := nowInUTC.In(wibLocation)

Se executarmos, obteremos a hora que corresponde ao local do fuso horário que definimos.

How to Handle Time Zones and Sync Your Software on the server side using Go

Teste e Validação

O último ponto não é menos importante, ou seja, teste e validação. Quando o processo de desenvolvimento muitas vezes faz com que os desenvolvedores cometam erros inesperados, o teste e a validação são sempre importantes.

Na discussão do ponto 2 acima, a função ParseTimezoneFromString foi importante no tratamento de nossos fusos horários. Testes e validações repetidos são importantes para que nossas aplicações obtenham resultados que atendam às nossas expectativas.

Para testes, recomenda-se a utilização de testes unitários, onde os testes serão realizados na menor unidade com diversos cenários que podem ser adicionados. Quanto mais cenários houver, menor será a probabilidade de lidar com essas diferenças de horário.

Conclusão

Lidar com fusos horários pode realmente ser complicado para desenvolvedores de back-end. Porém, é importante lembrar que cada tarefa desafiadora que superamos contribui para o nosso crescimento e aprimoramento de habilidades. O gerenciamento adequado de fusos horários não é apenas uma necessidade técnica, ele garante precisão no agendamento e fornece uma experiência tranquila para os usuários de nossos aplicativos em diferentes regiões.

Os pontos compartilhados neste artigo sobre armazenamento de horários em UTC, conversão para horários locais do usuário e implementação de funções de conversão robustas são pontos de partida para resolver esse problema complexo. No entanto, reconheço que pode haver deficiências ou áreas para melhoria nas abordagens discutidas. É por isso que contribuições e sugestões adicionais da comunidade de desenvolvedores são inestimáveis.

Espero sinceramente que os insights e exemplos de código fornecidos neste artigo sejam úteis para você no futuro, quando você encontrar desafios relacionados ao fuso horário em seus projetos. Lembre-se, o objetivo é criar aplicativos que funcionem perfeitamente para os usuários, independentemente de sua localização geográfica.

Vamos continuar esta discussão na seção de comentários abaixo. Eu adoraria ouvir sobre suas experiências ao lidar com fusos horários, quaisquer desafios que você enfrentou ou abordagens alternativas que você considerou eficazes. Seus insights podem ser extremamente valiosos para mim e para outros leitores que enfrentam problemas semelhantes.

Obrigado pela leitura e espero que este artigo seja útil em sua jornada de desenvolvimento. Vamos continuar aprendendo e melhorando juntos! ?

Lendo referências

  • Fuso horário
  • O que é um fuso horário?
  • Como lidar com fusos horários e sincronizar seu software com clientes internacionais
  • Lidando com fusos horários no desenvolvimento web
  • Trabalhando com datas e horas no Go: tratamento de fusos horários e formatação
Declaração de lançamento Este artigo foi reproduzido em: https://dev.to/tentanganak/how-to-handle-time-zones-and-sync-your-software-on-the-server-side-using-go-16ip?1Se houver houver qualquer violação, entre em contato com [email protected] para excluir
Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3