Python datetime: Como definir data e hora em Python?

Alura
Yan Orestes
Yan Orestes

Compartilhe

O que é a biblioteca datetime do Python? 

Ao lidar com sistemas que dependem do registro de tempo, como controle de presença, é essencial trabalhar com datas e horários de forma precisa.  

Pense que uma empresa nos contratou para criar um sistema de ponto que registra a entrada e saída de funcionários e exibe a data e a hora a cada ação. Para essa situação, utilizamos a biblioteca datetime do Python

Ao longo deste artigo, você vai aprender como obter a data atual, exibir horários no formato adequado e trabalhar com datas em diferentes contextos utilizando o datetime

Banner promocional da Alura destacando oferta especial com até 40% de desconto em cursos de tecnologia. A mensagem convida a transformar a carreira na maior escola tech da América Latina, com botão “Aproveite” para acessar a promoção.

Como usar date e obter a data atual em Python com datetime 

Com o módulo datetime da biblioteca nativa do Python, conseguimos pegar a data atual através da classe date, basta a importarmos e chamarmos o método today()

from datetime import date 
data_atual = date.today() 
print(data_atual)

Como esperado: 

2018-03-01 

Mas atenção... seria interessante imprimir a data no formato brasileiro (DD/MM/AAAA) para evitar confusões. O problema é que a classe date automaticamente usa o padrão ANSI ao imprimir. 

Como formatar uma data em Python para o formato brasileiro 

Como a classe date consegue nos fornecer separadamente cada seção da data, podemos resolver esse problema com uma simples formatação de string

data_em_texto = ‘{}/{}/{}’.format(data_atual.day, data_atual.month, 
data_atual.year)

Que resulta em: 

1/3/2018 

Já melhorou bastante, mas ainda não é exatamente o que queríamos. Repare que tanto o dia como o mês estão sem o prefixo 0, saindo do padrão pretendido. Nesse caso poderíamos até contornar isso simplesmente adicionando um 0 antes: 

data_em_texto = ‘0{}/0{}/{}’.format(data_atual.day, data_atual.month, 
data_atual.year)

O que daria certo, mas traria problemas caso o dia ou o mês fossem maiores ou iguais a 10: 

010/010/2018 

Esses são problemas comuns enfrentados por pessoas que estão aprendendo Python para web

Como formatar data e hora em Python com strftime()  

Para evitar maiores complicações, a classe date soluciona isso com um único método - o strftime(), que toma como parâmetro a formatação que queremos em nossa string de data e, desse modo, nos dá maior liberdade para decidirmos como queremos exibir a data. 

Esta formatação usa códigos melhor explicados na documentação. Ao final do texto, também damos uma explicação breve neles. No nosso caso fica assim: 

data_em_texto = data_atual.strftime(‘%d/%m/%Y’) 
print(data_em_texto)

E agora sim: 

01/03/2018 

Ou, no caso do nosso exemplo que resultou em 010/010/2018

10/10/2018 

Agora só precisamos dar um jeito de armazenar o horário também. Quem será que pode cuidar disso? Como você deve ter imaginado, o mesmo módulo datetime do qual importamos a classe date também possui classes que facilitam a manipulação de horários. 

Como usar datetime em Python para data e hora juntos  

Enquanto podemos sim usar o tipo time, destinado exclusivamente para horários, o módulo nos dá uma solução muito mais apropriada para o nosso problema com o tipo datetime - sim, tem o mesmo nome do módulo, cuidado com a confusão! 

Uma das vantagens da classe datetime é que ela consegue cuidar da data e do horário ao mesmo tempo. A única diferença em nosso uso é que, em vez do método today(), usaremos o método now()

from datetime import datetime 
data_e_hora_atuais = datetime.now() 
data_e_hora_em_texto = data_e_hora_atuais.strftime(‘%d/%m/%Y’) 
print(data_e_hora_em_texto)

O resultado é como o anterior: 

01/03/2018 

Opa! Apesar de já estarmos usando a classe datetime, que incorpora o horário, precisamos declarar na formatação que passamos como parâmetro para o strftime() que queremos mostrar a hora e o minuto, também: 

data_e_hora_em_texto = data_e_hora_atuais.strftime(‘%d/%m/%Y %H:%M’) 
print(data_e_hora_em_texto)

e agora sim: 

01/03/2018 12:30 

Perfeito! Até agora aprendemos a pegar a data atual com a classe date, datetime e até aprendemos a formatar datas, transformando-as em strings. Mas e se precisássemos fazer o caminho contrário? 

Como converter string para datetime em Python (data e hora)  

Se tivéssemos uma string de data e quiséssemos transformar em datetime, o que faríamos? Novamente, um simples método resolve tudo, dessa vez o strptime(), da própria classe datetime

from datetime import datetime 
data_e_hora_em_texto = ‘01/03/2018 12:30’ 
data_e_hora = datetime.strptime(data_em_texto, ‘%d/%m/%Y %H:%M’)

E tudo certo! Entretanto, o chefe da empresa foi testar o programa em outros computadores e alguns imprimiam horários diferentes. Por quê? 

Ajustando o fuso horário (timezone) na data e hora em Python 

Chequei as configurações de um desses computadores e descobri que o relógio dele estava com um fuso horário diferente do daqui de São Paulo, onde está a empresa. 

Não podemos deixar que o tempo no nosso programa dependa de cada máquina, porque não temos como garantir que todas as máquinas que rodarem esse programa estarão com o fuso horário que queremos. O ideal, então, seria forçar o fuso horário de São Paulo. 

Como definir o timezone em Python com a classe timezone  

A partir do Python 3, temos a classe timezone, também do módulo datetime

from datetime import datetime, timezone 
data_e_hora_atuais = datetime.now() 
fuso_horario = timezone() 
print(fuso_horario)

Vamos ver o que é impresso na tela: 

Traceback (most recent call last): 
  File "teste.py", line 4, in > 
    fuso_horario = timezone() 
TypeError: Required argument 'offset' (pos 1) not found

A exceção TypeError que recebemos indica que o argumento offset, esperado no construtor timezone, não foi encontrado. Realmente, não colocamos esse argumento. Mas o que ele significa? 

O parâmetro offset representa a diferença entre o fuso horário que queremos criar e o Tempo Universal Coordenado (UTC). No caso, em São Paulo, temos uma diferença de -3 horas, mais conhecida como UTC-3. Sabendo disso, vamos tentar novamente: 

fuso_horario = timezone(-3) 
print(fuso_horario)

Agora que configuramos o parâmetro offset, vamos ver o que aparece na tela: 

Traceback (most recent call last): 
  File "teste.py", line 4, in <module> 
    fuso_horario = timezone(-3) 
TypeError: timezone() argument 1 must be datetime.timedelta, not int

Dessa vez a mensagem da exceção é diferente, indicando que o argumento passado para o construtor timezone deve ser do tipo datetime.timedelta, não um número inteiro, que foi o que passamos. 

Como calcular diferença de datas e horários em Python com timedelta  

A classe timedelta tem a finalidade de representar uma duração e, no nosso caso, uma diferença entre horários. Vamos, agora, instanciá-la em uma variável e tentar imprimir, para ver o que acontece: 

diferenca = timedelta() 
print(diferenca)

Olha o que apareceu: 

0:00:00 

Tudo bem, 0 dias, 0 horas e 0 minutos. Mas precisamos que nosso objeto timedelta corresponda à diferença do UTC, as -3 horas: 

diferenca = timedelta(-3) 
print(diferenca)

E agora, o que aparece? 

-3 days, 0:00:00 

Mas o quê? -3 dias? A gente queria -3 horas! O problema é que o construtor timedelta recebe vários outros argumentos além da hora, nessa ordem: 

  • days (dias) 
  • seconds (segundos) 
  • microseconds (microsegundos) 
  • milliseconds (milisegundos) 
  • minutes (minutos) 
  • hours (horas) 
  • weeks (semanas) 

Então se a gente só manda um -3 para ele, esse número é interpretado como se fosse em dias. Podemos passar 0 para os primeiros 5 parâmetros e -3 para as horas, mas isso é um pouco estranho, considerando que, de fato, queremos definir apenas as horas

Usando a funcionalidade que o Python tem dos parâmetros nomeados, é possível especificar que estamos definindo o parâmetro de horas (hours), da seguinte forma: 

diferenca = timedelta(hours=-3) 
print(diferenca)

E dessa vez: 

-1 day, 21:00:00 

Ué, se a gente colocou -3, por que apareceu tudo isso? Acontece que o timedelta entende -3 horas como 0 dias, 0 horas e 0 minutos - 3 horas, ou seja, -1 dia,21 horas

Como corrigir o timezone e exibir hora correta em Python  

Vamos, agora, criar um objeto timezone correspondente ao UTC-3, indicando essa diferença do UTC como parâmetro do construtor: 

fuso_horario = timezone(diferenca) 
print(fuso_horario)

Temos justamente o que queríamos: 

UTC-03:00 

Finalmente, podemos converter o tempo da máquina para o de São Paulo, usando o método astimezone()

data_e_hora_sao_paulo = data_e_hora_atuais.astimezone(fuso_horario) 
data_e_hora_sao_paulo_em_texto = data_e_hora_sao_paulo.strftime(‘%d/%m/%Y %H:%M’) 
print(data_e_hora_sao_paulo_em_texto)

Agora está tudo padronizado: 

01/03/2018 12:30 

Temos tudo resolvido com o fuso horário agora, mas e se fossemos mostrar nosso código para outro programador, ele entenderia o que significa o -3? Não fica muito fácil, né? 

Aliás, para todo fuso horário teríamos que pesquisar qual a sua diferença do UTC, o que é um problema chato. Será que não há uma maneira mais simples e elegante para resolver essa questão? 

Como usar o módulo zoneinfo para timezone em Python   

O Python oferece suporte nativo para manipulação de fusos horários através do módulo zoneinfo

Essa funcionalidade utiliza o banco de dados da IANA (Internet Assigned Numbers Authority), que é o padrão mundial para referenciar localidades e seus respectivos horários. 

Para quem utiliza o Windows, é recomendável instalar o pacote tzdata via terminal para garantir que as informações de fuso estejam disponíveis: 

pip install tzdata

Com o módulo importado, podemos utilizar a classe ZoneInfo para converter horários: 

from datetime import datetime 
from zoneinfo import ZoneInfo 
# Obtemos a data e hora atual do sistema 
data_e_hora_atuais = datetime.now()  
# Definimos o fuso horário que desejamos aplicar (ex: São Paulo) 
fuso_horario = ZoneInfo('America/Sao_Paulo')  
# Aplicamos a conversão utilizando o método astimezone 
data_e_hora_sao_paulo = data_e_hora_atuais.astimezone(fuso_horario)  
# Formatamos o resultado para o padrão brasileiro (Dia/Mês/Ano Hora:Minuto) 
data_e_hora_formatada = data_e_hora_sao_paulo.strftime('%d/%m/%Y %H:%M') 
print(f"Horário em São Paulo: {data_e_hora_formatada}")

Uma dúvida que pode surgir é: "como eu sei o nome correto do fuso horário que devo usar?". O zoneinfo permite listar todas as opções de localidades suportadas pelo seu sistema através do método available_timezones. 

import zoneinfo  
# Listando todos os fusos horários disponíveis em ordem alfabética 
for tz in sorted(zoneinfo.available_timezones()): 
print(tz)

Ao executar esse código, você verá uma lista com centenas de opções, como America/Manaus, Europe/Paris ou Asia/Tokyo. 

Trabalhar com datas será muito mais simples a partir de agora! 

Principais códigos de formatação de data e hora em Python (strftime)  

Ao longo desse post, usamos diversas vezes alguns códigos de formatação de datas, como por exemplo o padrão %d/%m/%Y %H:%M. Mas o que significa isso? 

Esses códigos são definidos pela documentação do strftime(3). Os usados em nossos exemplos são: 

  • %d - O dia do mês representado por um número decimal (de 01 a 31) 
  • %m - O mês representado por um número decimal (de 01 a 12) 
  • %Y - O ano representado por um número decimal incluindo o século 
  • %H - A hora representada por um número decimal usando um relógio de 24 horas (de 00 a 23) 
  • %M - O minuto representado por um número decimal (de 00 a 59) 

Resumo: Como manipular data e hora em Python usando datetime  

Começamos o conteúdo com a necessidade de manipular datas no Python e vimos como fazer isso utilizando o tipo date. Aprendemos a incluir o horário com a classe datetime e a formatar essas informações em uma string de fácil leitura. 

Acabamos tendo um problema com o fuso horário e vimos como resolver com a classe timezone no Python 3. Também vimos uma maneira mais simples de solucionar esse problema com a biblioteca zoneinfo. 

Como aprender mais sobre Python?

Se você quer aprender mais sobre Python, busque aprofundar seus estudos em manipulação de datas, horários e outros recursos da linguagem. Confira a nossa carreira Desenvolvimento Back-End Python 

Até mais! 

Veja outros artigos sobre Programação