Trabalhar com data e hora em sistemas modernos requer entender completamente o uso de fuso horários. Uma aplicação web ou mobile é composta, em sua maioria das vezes, de banco de dados, servidor e cliente (navegador web ou aplicativo). É necessário entender bem que o fuso de cada uma dessas camadas pode ter especificações diferentes que podem gerar confusões ao implementar seu sistema.
A maioria dos bancos de dados fornecem alguns tipos de dados para armazenamento de data (DATE
), data e hora (DATETIME
) ou apenas hora (TIME
). Tais tipos podem considerar as informações de fuso ou não. A grande confusão ocorre quando tais tipos não levam em consideração o fuso, o que acabam ficando dependente de uma configuração correta do servidor e cliente para que não haja diferença de horários.
Os tipos mais comuns são:
DATE
.O timestamp é útil para registrar log, e para determinar se A aconteceu antes ou depois de B, mesmo que A e B tenham acontecido em lados opostos do planeta. Por outro lado, o timestamp é inadequado para registrar datas e horas "civis" porque a hora e até a data muda conforme o fuso horário em que o timestamp é interpretado.
Nem sempre a melhor opção é óbvia. Por exemplo, registrar a data de nascimento com DATETIME ou TIMESTAMP? De um ponto de vista matemático, o TIMESTAMP seria ideal porque um bebê nasce num momento bem determinado. Por outro lado, a data e hora de nascimento têm efeitos civis - colocar a data de nascimento diferente da carteira de identidade pode causar um monte de aborrecimentos - então é melhor usar DATETIME e o local de nascimento, já que o fuso horário é de conhecimento público.
Resumindo, ao usar DATE, DATETIME ou TIME, seu servidor tem que conhecer em qual fuso horário você deseja obter e gravar esses valores, para esses casos, recomendamos que o banco e o servidor estejam no mesmo fuso horário.
O servidor normalmente tem apenas uma configuração global de fuso horário. Ao gravar ou obter campos do tipo DATE
, DATETIME
ou TIME
, ele vai usar a informação de fuso configurada para suas conversões internas. Ao gravar ou obter campos do tipo TIMESTAMP
, ele vai simplesmente respeitar o que está informado no valor, ou seja, as informações do fuso horário do servidor não interferem. O Cronapp usa o JAVA como plataforma base do servidor e o tipo java.util.Date
para representação de todos os tipos internos: data, data e hora, hora e timestamp. O uso de um único tipo é um padrão especificado pela Java Persistence Interface (JPA). Para "entender" o que significa cada tipo, o JPA exige anotações acima da declaração do tipo do atributo na classe que representa a tabela do banco, mas isso não será entrado em detalhes, viso que é um assunto mais high code que fica abstraído para quem usa a IDE apenas como low code.
O fuso horário do aplicativo é o que pode sofrer mais variações. Na maioria das vezes em sistemas modernos, os usuários estão ao redor do mundo e, sendo assim, é preciso aceitar entradas e exibições de datas e horas considerando o fuso horário de quem está digitando ou lendo.
Exemplo: Imagine um sistema de cadastro de eventos. Nesse sistema, usuários do mundo inteiro poderão cadastrar eventos que devem acontecer segundo o contexto de fuso de quem cadastra, porém, para outros usuários ao redor do mundo, tais horários podem ser exibidos com diferenças. Um evento às 10:00 de Londres ocorre às 07:00 do Brasil ou um evento 1:00 de Londres do dia 10/11/2019 ocorre às 22:00 do dia 09/11/2019 no Brasil.
O Cronapp IDE procurou deixar tudo mais simples para seus usuários, inclusive aqueles que não têm pretensão de que seus sistemas funcionem em diferentes fusos horários. Para isso, vale a pena entender bem os recursos e configurações que o Cronapp oferece, para que não haja desperdício de tempo com tentativas, erros ou suporte.
Clique no menu do sistema Projeto > Configurações para abrir a janela de configurações, clique na aba Configurações de Projeto, em seguida, expanda a subaba Banco de Dados para encontrar dois campos importantes (Figura 1):
DATE
, DATETIME
e TIME
terão o fuso da opção selecionada. O campo TIMESTAMP
não é afetado por essa opção (a não ser no formato textual) e seu valor padrão é (GMT00:00) UTC.Figura 1 - Campos de configuração de fuso horário na IDE
O Diagrama de dados oferece os 4 tipos mais comuns de data de bancos de dados:
DATE
e o fuso será considerado como informado nas configurações do projeto;DATETIME
e o fuso será considerado como informado nas configurações do projeto;TIME
e o fuso será considerado como informado nas configurações do projeto;TIMESTAMP
.Em vários campos é possível exibir ou editar uma data, data e hora ou hora e possui algumas opções em sua propriedade Tipo que devem ser consideradas. Eles terão comportamentos diferentes a depender da configuração feita nas Configurações do Projeto (Figura 1). Vários campos podem receber datas.
Para entender mais sobre máscaras no cliente, leia o documento Formatação de máscaras na camada cliente. |
Em componentes visuais como Entrada de texto, Título, Lista e outros, é possível usar as propriedades Tipo e Máscara (Figura 2.1).
Figura 2.1 - Campos Tipo e Máscara nas propriedades de uma entrada de texto
Também é possível acessa a janela da propriedade Conteúdo ou a janela da opção Editar expressão para qualquer propriedade, nela podemos definir o Tipo e a Máscaras que será aplicada (Figura 2.2).
Figura 2.2 - Janela da opção Editar expressão das propriedades
A exibição desses campos será influenciada pelo Tipo e pela Máscara que serão escolhidas. As opções para o Tipo podem ter os seguintes valores para uma data, data e hora ou hora:
Date
): exibe a data desconsiderando a hora, mesmo que no diagrama tenha sido usado algum tipo que considere a hora. Se o tipo no diagrama tiver hora, ela será armazenada como 00:00:00. Se a opção Converter Fuso Horário do Cliente estiver marcada, esse campo irá exibir o fuso da opção, caso contrário usará o fuso do navegador web ou aplicativo.Date and Time
): exibe a data e hora. Se a opção Converter Fuso Horário do Cliente estiver marcada, esse campo irá exibir o fuso da opção, caso contrário usará o fuso do navegador web ou aplicativo.Date and Time Local
): exibe a data e hora. Será exibido no fuso local do navegador/aplicativo.Time
): exibe apenas a hora. Se o tipo no diagrama tiver data, ela será armazenada como 01/01/1970.Time Local
): exibe apenas a hora. Se o tipo no diagrama tiver data, ela será armazenada como 01/01/1970. Será exibido no fuso local do navegador/aplicativo.Month
): exibe apenas o mês da data (Janeiro, Fevereiro etc.). Ao entrar uma nova data, usará dia, ano e hora atuais.Week
): exibe apenas o dia da semana da data (Segunda-Feira, Terça-Feira etc.). Ao entrar uma nova data, usará mês, ano e hora atuais.Exemplo: Um campo com a data 22/11/2000 10:00:00 UTC (00:00). Se estivermos com a opção Converter Fuso Horário do Cliente e o fuso escolhido tiver sido UTC (00:00) e o fuso do cliente seja America/Sao_Paulo (-03:00), teremos os valores para os diferentes tipos:
Tipo | Valor |
---|---|
Date | 22/11/2000 |
Date and Time | 22/11/2000 10:00:00 |
Date and Time Local | 22/11/2000 07:00:00 (Será exibido no fuso local do navegador/aplicativo) |
Time | 10:00:00 |
Time Local | 07:00:00 (Será exibido no fuso local do navegador/aplicativo) |
Month | Novembro |
Week | Quarta-Feira |
A propriedade Tipo irá determinar o padrão da janela de escolha rápida de datas, horas, meses, semanas, dias etc. Na Figura 2.3 temos o componente Entrada de texto configurado com o Tipo Time
.
Figura 2.3 - Janela de escolha rápida para o tipo Time
A propriedade Máscara possui alguns modelos pré-definidos, mas é possível configurá-los manualmente. Saiba mais na documentação Formatação de máscaras na camada cliente.
O bloco de programação fornece algumas funções para tratamento de datas. Algumas das mais importantes são:
É possível tratar as máscaras no lado Servidor ou Cliente, porém existem diferenças.
Na camada Servidor, a especificação de máscaras é diferente do cliente, inserimos o formato "MM-dd-yyyy", onde "MM" é o mês em 2 digitos, "dd" é o dia em 2 dígitos e "yyyy" é o ano em 4 digitos. Segue um exemplo do uso da máscara no servidor:
Acesse a documentação Formatação de máscaras na camada servidor para mais detalhes sobre o uso da mascará na camada Servidor. |
Figura 3.1 - Configurando a máscara através do bloco Formatar data Servidor
Na camada Cliente, a forma que é escrita a máscara é diferente do servidor, aqui, inserimos o formato "MM-DD-YYYY", onde "MM" é o mês em 2 digitos, "DD" é o dia em 2 dígitos e "YYYY" é o ano em 4 dígitos, Segue um exemplo do uso da máscara no servidor:
Acesse a documentação Formatação de máscaras na camada cliente para mais detalhes sobre o uso da mascará na camada Cliente. |
Figura 3.2 - Configurando a máscara através do bloco Formatar data Cliente
Caso um objeto do tipo data seja enviado para qualquer função que espere um texto, ele será representado pelo formado ISO 8601 no fuso horário especificado para a aplicação.
Ex.: JSON enviado para um serviço REST.
Tenham atenção ao visualizar o formato ISO 8601 das datas. Datas com textos diferentes podem representar o mesmo valor, pois o fuso pode estar escrito de forma diferente:
Ex.: 2019-09-22T00:00:00Z
é igual a 2019-09-21T09:00:00-03:00
.
Nesta página
Conteúdo complementar