Introdução
Datas e horas são a espinha dorsal de quase qualquer processo empresarial: desde quando um pedido foi feito até a hora exata de uma entrega ou o registo de entrada de um colaborador. No Odoo, o campo Datetime é a forma padrão de registar esse tipo de informação com precisão temporal, combinando data e hora num único valor útil para relatórios e automações.
Ao contrário do campo Date, que guarda apenas a data do calendário, o Datetime inclui a hora (horas, minutos e segundos). Essa diferença ganha relevância sempre que é preciso rastrear eventos com detalhe ou quando utilizadores em fusos horários diversos interagem com os mesmos registos — aí a componente horário e a conversão entre fusos fazem toda a diferença.
Este guia reúne o essencial sobre o campo Datetime no Odoo: o que ele guarda, como o framework o trata internamente, de que forma o utilizador o vê, como o adicionar via Studio, código Python ou API, e exemplos práticos de utilização em processos empresariais reais.
O que é o campo Datetime no Odoo
No ORM do Odoo, fields.Datetime representa um instante combinado de data e hora com precisão de segundos. Em PostgreSQL corresponde a uma coluna TIMESTAMP. Odoo armazena esses valores internamente em UTC e converte automaticamente para o fuso horário do utilizador ativo quando os mostra na interface.
Para o utilizador, o campo Datetime surge como um controlo que junta calendário e hora: escolhe-se o dia e define-se a hora na mesma entrada. Em vistas de lista ou relatórios, o valor é formatado segundo o idioma e o fuso configurado do utilizador, garantindo leitura consistente para cada contexto regional.
Exemplificando num modelo Python, um campo Datetime é declarado junto dos restantes campos do modelo para armazenar um carimbo temporal que representa um evento específico no registo.
from odoo import fields, models
class SaleOrder(models.Model):
_inherit = 'sale.order'
x_confirmed_on = fields.Datetime(
string='Confirmed On',
default=fields.Datetime.now,
readonly=True,
copy=False,
)
O parâmetro string define o rótulo exibido na interface; default indica o valor inicial (a data/hora atual quando for usado corretamente); readonly
No Odoo Studio este campo aparece como Date & Time. Campos criados pelo Studio recebem automaticamente um prefixo x_studio_. Se o campo for criado por código ou via API, o nome técnico é definido pelo desenvolvedor ou script.
Como funciona o campo
Quando define um campo Datetime num módulo, o Odoo trata de criar a coluna correspondente na base de dados durante a instalação ou atualização do módulo — não são necessárias migrações SQL manuais para a maioria dos casos.
Um ponto que costuma surpreender é o comportamento com fusos horários: o valor é guardado em UTC. Por exemplo, uma reunião marcada às 15:00 em Paris será armazenada como 13:00 UTC. Outro utilizador em Nova Iorque verá essa mesma reunião convertida para o seu fuso (09:00). O ORM gere essa conversão de forma transparente com base no fuso configurado no perfil de cada utilizador.
Atributos-chave do campo
A seguir estão as propriedades mais importantes que controlam um campo Datetime no Odoo e como elas influenciam comportamento e integridade dos dados.
- default: costuma usar-se
fields.Datetime.nowcomo referência para preencher automaticamente o carimbo temporal no momento de criação do registo, garantindo timestamps correctos por registo. - required: torna o campo obrigatório, validando que o formulário ou o modelo não aceitarem registos sem essa informação essencial.
- readonly: impede a edição direta pelo utilizador — apropriado para timestamps que devem refletir eventos do sistema e não alterações manuais.
- compute: liga o campo a um método Python que calcula o seu valor dinamicamente a partir de outros campos ou regras de negócio.
- store: quando usado com
compute, persiste o valor calculado na base de dados para permitir pesquisas, ordenação e relatórios eficientes. - copy: controla se o valor é duplicado ao criar uma cópia do registo. Normalmente é
True, mas para carimbos de evento deve serFalsepara evitar contaminação de histórico. - index: cria um índice na base de dados, útil em campos que se usam frequentemente em filtros e pesquisas em tabelas grandes, como datas previstas de operações.
Como se apresenta nas vistas
Em formulários, o Datetime aparece como um seletor que integra calendário e hora. Em listas, surge já formatado conforme o idioma do utilizador. Nos filtros de pesquisa, suportam-se intervalos e operadores temporais (antes, depois, entre), permitindo consultas precisas por períodos.
Também é comum combinar um Datetime com widgets como date_range para permitir a seleção directa de janelas temporais — prático para agendar janelas de atendimento ou janelas de produção.
Datetime vs Date: escolher corretamente
A dúvida frequente é quando optar por fields.Datetime em vez de fields.Date. A regra prática: use Date quando só interessa o dia; use Datetime quando a hora (horas/minutos) importa para o processo.
Use Date para prazos de pagamento, aniversários, datas de validade de produtos ou renovações contratuais — situações em que a hora do dia não altera a lógica de negócio.
Use Datetime para carimbos de confirmação de encomendas, início de reuniões, registos de presença de colaboradores, ou operações logísticas agendadas — onde a precisão horária é crítica.
Evitar Datetime quando não é necessário evita complexidade desnecessária com fusos horários. Pergunte sempre: a hora do dia faz diferença para esta regra de negócio? Se não fizer, escolha Date.
Casos de uso empresariais
O campo Datetime aparece praticamente em todos os módulos do Odoo; seguem-se exemplos práticos que ilustram a sua utilidade em processos reais.
CRM: acompanhamento de atividades
No CRM, campos Datetime são essenciais para medir tempos de resposta: um campo que registe quando um lead entrou em progresso, ou a data limite de follow-up, permite aos gestores identificar leads estagnados, medir SLA de equipa e automatizar alertas. Campos personalizados podem registar quando foi enviado um orçamento ou quando ocorreu uma chamada específica.
Vendas: carimbos de confirmação de encomenda
No módulo de Vendas, o campo que regista a confirmação da encomenda captura o instante exacto em que a venda foi validada. É vital para relatórios por hora/dia, análise de eficiência de processamento e auditoria de alterações posteriores à confirmação. Filtrar encomendas por esse campo é uma prática padrão em relatórios comerciais.
Inventário: datas de transferências agendadas
No Inventário, o campo scheduled_date permite planear entradas e saídas. Fluxos automáticos podem comparar essa data com o tempo atual para disparar notificações — por exemplo, avisar clientes se uma entrega estiver atrasada X horas, reduzindo a necessidade de contacto manual.
Fabrico: horários de produção
Nas ordens de fabrico, registar o início e o fim da produção com precisão permite calcular eficiência, gerar planos de capacidade e detectar gargalos por turno ou operador. Para empresas com múltiplos turnos, o detalhe horário é imprescindível para comparar produção planeada versus realizada.
RH: gestão de presenças e férias
No módulo de RH, a assiduidade depende de registos Datetime para entradas/saídas. Pedidos de ausência usam Datetime para definir início e fim exactos. Cálculo de salários e horas extraordinárias depende destes carimbos serem precisos até ao minuto; falhas ou lacunas podem impactar directamente a folha de pagamento.
Como criar ou personalizar o campo Datetime
Existem três formas principais de adicionar um campo Datetime a um modelo Odoo, consoante prefira uma abordagem sem código ou orientada a desenvolvedor.
Com Odoo Studio (sem código)
Odoo Studio permite criar campos sem escrever código, ideal para utilizadores funcionais que querem ajustar formulários rapidamente.
- Abra o Odoo Studio a partir do menu principal.
- Vá ao formulário onde pretende inserir o campo.
- Arraste o componente Date & Time da barra lateral para o local desejado no formulário.
- Defina o rótulo, se é obrigatório e, se for o caso, um valor por defeito nas propriedades do campo.
- Guarde e feche o Studio.
O Studio cria automaticamente o campo com prefixo x_studio_ e atualiza a vista — o Odoo trata da criação da coluna na base de dados sem necessidade de intervenção manual. É a solução recomendada para utilizadores de negócio que querem adicionar carimbos temporais sem envolver desenvolvedores.
Via Python num módulo personalizado
Para personalizações controladas por versão e deploys reprodutíveis, defina o campo em ficheiros Python do módulo — é a forma indicada para ambientes de produção com controlo de código-fonte.
from odoo import fields, models
class ResPartner(models.Model):
_inherit = 'res.partner'
x_last_contact_date = fields.Datetime(
string='Last Contact Date',
default=fields.Datetime.now,
copy=False,
)
Depois de declarar o campo no modelo, inclua-o na vista XML correspondente. Durante a instalação/actualização do módulo, o Odoo cria a coluna TIMESTAMP automaticamente — não é necessário escrever SQL manualmente.
Usando a API XML-RPC
Se a sua automação ou pipeline precisa de criar campos programaticamente, pode fazê-lo através da API XML-RPC do Odoo.
field_id = models.execute_kw(
ODOO_DB, uid, ODOO_API_KEY,
'ir.model.fields', 'create',
[{
'name': 'x_last_contact_date',
'field_description': 'Last Contact Date',
'model_id': model_id,
'ttype': 'datetime',
'state': 'manual',
}]
)
Ao definir ttype como 'datetime', instrui o Odoo a criar um campo Datetime. O atributo state: 'manual' sinaliza que foi criado fora de um módulo (como via Studio ou API) — o comportamento correcto para campos geridos dinamicamente por scripts de configuração remota.
Boas práticas
1. Use fields.Datetime.now como referência de função, não chamada
Ao definir um default escreva default=fields.Datetime.now sem parêntesis. Se usar parêntesis, a função é avaliada na carga da classe e todos os registos criados na vida do processo Odoo terão o mesmo timestamp congelado — um erro silencioso e difícil de detectar.
2. Configure copy=False em carimbos de evento
Campos que registam um evento (confirmação, conclusão) devem ter copy=False. Ao duplicar registos, estes carimbos não devem ser transportados para o novo registo, caso contrário o histórico fica comprometido e relatórios tornam-se incorretos.
3. Sempre escreva em UTC quando usar a API
Ao criar/atualizar via XML-RPC, passe valores Datetime em UTC no formato YYYY-MM-DD HH:MM:SS. A API grava exactamente o que recebe como se fosse UTC; enviar horas locais causa erros de offset silenciosos que são difíceis de diagnosticar depois.
4. Use readonly para carimbos gerados automaticamente
Deixe carimbos de eventos em readonly na interface para evitar edições manuais. Se for necessário permitir alterações, controle-as por permissões de acesso a campo em vez de deixar o campo aberto a todos os utilizadores.
5. Prefira Date quando a hora não for pertinente
Se só interessa o dia (prazos, renovações, vencimentos), use fields.Date. Evitar Datetime quando não é necessário reduz a complexidade com fusos horários e simplifica a manutenção do modelo de dados.
Erros comuns
Confusão com fusos ao ler valores crus
A fonte mais comum de erros é ler timestamps directamente da base de dados ou via API e assumir que representam a hora local. O valor bruto vem em UTC; relatórios ou integrações que usam esse output sem conversão acabam com horas erradas. Sempre aplique conversão de fuso no cliente ou no processo que apresenta os dados ao utilizador.
Escrever horas localizadas via API
Se enviar um timestamp já em hora local para a API, o Odoo vai armazená-lo como se fosse UTC. Uma reunião marcada às 15:00 em Paris passada como 2026-01-01 15:00:00 pode aparecer deslocada para o utilizador parisiense após aplicação do mecanismo de conversão, dependendo do período do ano. Este tipo de erro normalmente só surge em produção com utilizadores em diferentes fusos a usarem o sistema.
Usar default=fields.Datetime.now() com parêntesis
Colocar parêntesis no default é um erro subtil mas grave: fields.Datetime.now() é avaliado no carregamento da classe e fixa o mesmo timestamp para todos os registos criados enquanto o worker estiver vivo. Os dados parecem existir, mas perdem valor analítico porque as datas ficam todas idênticas.
Esquecer copy=False em carimbos de evento
Sem copy=False, ao duplicar um registo os campos Datetime são copiados, contaminando o histórico. Um registo duplicado não deve herdar, por exemplo, a data de confirmação do original — essa pequena configuração evita relatórios e trilhas de auditoria enganadoras.
Usar Datetime quando Date basta
Escolher Datetime para campos que só precisam da data adiciona complexidade desnecessária: aparece um componente horário irrelevante, são efectuadas conversões de fuso sem benefício e a interface fica mais densa. Adote o tipo mais simples que satisfaça o requisito de negócio.
Conclusão
O campo Datetime é um dos mais úteis no Odoo quando a precisão temporal é necessária. Desde a abertura de um lead até ao registo de início de produção ou presença de colaboradores, está presente em quase todos os módulos e suporta análises e automações chave.
O ponto central a reter é o modelo de armazenamento em UTC: a base de dados guarda tudo em UTC e a interface converte para o fuso do utilizador. A maioria dos bugs relacionados com fusos em integrações Odoo provém de não ter esta regra em mente ao ler ou escrever dados externamente.
Além disso, usar a sintaxe correcta para defaults, aplicar copy=False onde faz sentido e escolher Date quando a hora não interessa mantém o modelo de dados limpo e a qualidade dos relatórios intacta.
Na Dasolo apoiamos empresas a implementar, personalizar e optimizar Odoo em todos os departamentos. Também ajudamos a desenhar modelos de dados seguros, a acrescentar campos customizados às suas operações e a desenvolver módulos completos quando necessário. Contacte-nos e falemos do seu projecto Odoo.