Salvar data em UTC mas validar de acordo com o fuso do app do cliente

Bom dia pessoal
Tenho uma API feita com Spring Boot e precisava que as datas salvas não tenham diferença de fuso.
Pelo que vi, o ideal seria salvar em UTC. Alterei a API para UTC e estava enviando a data no Json já convertida do lado do cliente para UTC.

O app precisa enviar 2 datas: menor e maior horário possível para início de um serviço.

Porém, na API tenho uma validação onde a menor data informada de agendamento não pode ser menor que 07:00 nem maior que 23:00 e também ambas as datas tem que ser no mesmo dia.

Então veja o exemplo:
Se informar menor horario como 28/07/2020 15:00 e maior como 22:30 (estando em GMT-3), a API deveria permitir. Porém, ao transformar essa data no app em UTC ela vira 28/07/2020 18:00 e 29/07/2020 01:30). Aí bate na API e dá data invalida (pq considera dias diferentes)

Como fariam para resolver isso? Usam essa pratica: converte tudo para UTC e depois, do lado do cliente ele converte de volta pro fuso atual?

1 curtida

Oi @alanbravin,

Como você percebeu salvar a data em UTC não é a solução perfeita para se trabalhar com datas.
Funciona muito bem quando você quer registrar quando um evento ocorreu.

Para agendamentos no futuro ou recorrentes, não é suficiente.

Um dos problemas você já mencionou. Também terá problema quando começar o horário de verão, por exemplo.

Acho que no seu caso vale a pena armazenar o horário informado pelo cliente e o timezone no formato completo, como listado aqui na coluna “TZ Database name”.

Armazenando esses dados, você pode sempre descobrir o horário em UTC, para comparações, mas também tem acesso a data local do usuário, onde pode fazer esse tipo de validação (depois das 7, antes das 22)

Aqui um artigo explicando mais sobre como lidar com datas: https://engineering.q42.nl/why-always-use-utc-is-bad-advice/

Li o artigo, bem interessante. Entendo agora que com o timezone + região consigo resolver até o horário de verão.

No caso, usaria o ZonedDateTime. Saberia me dizer se o spring já faria o deserialize desse tipo de dados e salvaria no banco, apenas informando o formato de data necessário?

Isso posso até achar na internet. Agora a pergunta mais importante: se entendi bem, eu mando a data do app como esta para o usuário (com timezone e região no formato), salvo ela desse jeito, valido o range de horário considerando esse timezone e também retorno para o usuário (no caso da listagem dos pedidos ) também nesse formato e o app trata de converter para a região do usuário (caso ela tenha mudado). Seria essa a dinâmica?

No caso, usaria o ZonedDateTime. Saberia me dizer se o spring já faria o deserialize desse tipo de dados e salvaria no banco, apenas informando o formato de data necessário?

Olha, tem tempo que não uso Spring, não sei se tem algo pronto nele para isso.

Seria essa a dinâmica?
Acredito que é isso mesmo.
Nesses casos é bom ter bem claro no seu sistema em que momentos essas conversões acontecem para você nem repetir nem deixar de fazer.