[resolvido] Serializando uma data (datetime) com Python.

Então você tenta converter um dicionário em json, esquece que tem um objeto la que é do tipo datetime e acaba recebendo um Exception do tipo TypeError com a mensagem “Object of type datetime is not JSON serializable”. Neste post mostro uma forma de resolver isso.

Vamos considerar o cenário abaixo:

from datetime import datetime
import json


if __name__ == '__main__':
    foo = json.dumps({"dt": datetime.now()})

Neste código, tento criar uma variável chamada foo, contendo a versão string de um dicionário simples, que possui apenas uma chave (dt) com o valor do dia/hora atual (datetime.now()).

A função dumps do json serve para fazer esta conversão, mas alguns objetos ela não consegue converter com o funcionamento padrão. Sendo assim, o código acima resultaria no erro:

TypeError: Object of type datetime is not JSON serializable

 

A primeira forma de resolver este problema seria tratando os objetos datetime antes de fazer a conversão, mas talvez fazer isso seja muito trabalhoso. Podemos contornar o problema criando um conversor padrão e utilizando ele na função dumps.

Primeiro, vamos ao conversor:

def dt_parser(dt):
    if isinstance(dt, datetime):
        return dt.isoformat()

O que a função acima faz?

  1. Confere se o objeto que foi passado para a função é do tipo datetime;
  2. Se for chama a função isoformat() deste objeto, que retorna a versão em string do objeto;

 

Simples assim. O próximo passo é utilizar este conversor na função dumps.

>>> foo = json.dumps({"dt": datetime.now()}, default=dt_parser)
>>> print(f"[{type(foo)}] {foo}")
[<class 'str'>] {"dt": "2019-06-05T22:18:51.052779"}

 

No código acima também faço uma chamada para a função dumps, mas desta vez inclui um novo argumento, o default. Ele serve como opção para utilizar quando um objeto não for serializavel da forma padrão. Exemplificando: Imagine um dicionario que possui três chaves: uma string, um integer e um valor datetime. Quando você utilizar a função json.dumps, ele vai conseguir converter a string e o integer, mas não sabe como converter o objeto datetime. Então a função vai recorrer ao que você informar no argumento default.

Por isso que nesta segunda tentativa, consegui converter o dicionario para string.

Se quiser, criei um exemplo para este post no meu Github.

 

Espero ter ajudado!

The following two tabs change content below.
Arquiteto de Software e Desenvolvedor Backend (quase Fullstack), geralmente trabalho com C#, PowerShell, Python, Golang, bash e Unity (esse é mais por hobby). Estou sempre buscando algo novo para aprender, adicionando novas ferramentas ao meu cinto de utilidades.
Posted in Dev, Python and tagged , , , , .