Desejo enviar um objeto datetime.datetime no formato serializado do Python usando JSON e desserializar no JavaScript usando JSON. Qual é a melhor maneira de fazer isso?
javascript
python
json
Peter Mortensen
fonte
fonte
Respostas:
Você pode adicionar o parâmetro 'default' ao json.dumps para lidar com isso:
Qual é o formato ISO 8601 .
Uma função de manipulador padrão mais abrangente:
Atualização: saída adicionada do tipo e do valor.
Atualização: também lida com a data
fonte
dthandler = lambda obj: obj.isoformat() if isinstance(obj, datetime) else json.JSONEncoder().default(obj)
Para projetos em vários idiomas, descobri que as seqüências contendo datas RfC 3339 são o melhor caminho a percorrer. Uma data da RfC 3339 é assim:
Eu acho que a maior parte do formato é óbvia. A única coisa um tanto incomum pode ser o "Z" no final. Significa GMT / UTC. Você também pode adicionar um deslocamento de fuso horário como +02: 00 para CEST (Alemanha no verão). Pessoalmente, prefiro manter tudo no UTC até que seja exibido.
Para exibição, comparações e armazenamento, você pode deixá-lo no formato de sequência em todos os idiomas. Se você precisar da data para cálculos, é fácil convertê-la novamente em um objeto de data nativo na maioria dos idiomas.
Portanto, gere o JSON assim:
Infelizmente, o construtor Date do Javascript não aceita seqüências de caracteres RfC 3339, mas existem muitos analisadores disponíveis na Internet.
O huTools.hujson tenta lidar com os problemas de codificação mais comuns que você pode encontrar no código Python, incluindo objetos de data / data e hora enquanto manipula fusos horários corretamente.
fonte
datetime
: datetime.isoformat () quanto porsimplejson
, que irá despejardatetime
objetos comoisoformat
seqüências de caracteres por padrão. Não há necessidade destrftime
hackers manuais .datetime
objetos para aisoformat
seqüência de caracteres. Para mim,simplejson.dumps(datetime.now())
os rendimentosTypeError: datetime.datetime(...) is not JSON serializable
json.dumps(datetime.datetime.now().isoformat())
é onde a mágica acontece.Eu resolvi isso.
Digamos que você tenha um objeto datetime do Python, d , criado com datetime.now (). Seu valor é:
Você pode serializá-lo para JSON como uma sequência de data e hora ISO 8601:
O exemplo de objeto datetime seria serializado como:
Esse valor, uma vez recebido na camada Javascript, pode construir um objeto Date:
A partir do Javascript 1.8.5, os objetos Date têm um método toJSON, que retorna uma string em um formato padrão. Para serializar o objeto Javascript acima de volta para JSON, portanto, o comando seria:
O que lhe daria:
Essa sequência, uma vez recebida em Python, pode ser desserializada de volta para um objeto datetime:
Isso resulta no seguinte objeto datetime, que é o mesmo com o qual você iniciou e, portanto, correto:
fonte
Usando
json
, você pode subclassificar JSONEncoder e substituir o método default () para fornecer seus próprios serializadores personalizados:Então, você pode chamar assim:
fonte
obj.isoformat()
. Você também pode usar o mais comumdumps()
chamada, que tem outros argumentos úteis (comoindent
): simplejson.dumps (myObj, cls = JSONEncoder, ...)Aqui está uma solução bastante completa para codificar e decodificar recursivamente os objetos datetime.datetime e datetime.date usando o
json
módulo de biblioteca padrão . Isso precisa do Python> = 2.6, pois o%f
código do formato datetime.datetime.strptime () é suportado somente desde então. Para suporte ao Python 2.5, solte%f
e retire os microssegundos da sequência de datas ISO antes de tentar convertê-lo, mas você perderá a precisão dos microssegundos, é claro. Para interoperabilidade com seqüências de datas ISO de outras fontes, que podem incluir um nome de fuso horário ou deslocamento UTC, também é necessário remover algumas partes da sequência de datas antes da conversão. Para um analisador completo de seqüências de datas ISO (e muitos outros formatos de data), consulte o módulo dateutil de terceiros .A decodificação funciona apenas quando as cadeias de datas ISO são valores em uma notação literal de objeto JavaScript ou em estruturas aninhadas em um objeto. As sequências de datas ISO, que são itens de uma matriz de nível superior, não serão decodificadas.
Ou seja, isso funciona:
E isso também:
Mas isso não funciona conforme o esperado:
Aqui está o código:
fonte
datetime.datetime.utcnow().isoformat()[:-3]+"Z"
se fosse exatamente o que JSON.stringify () produz em javascriptSe você tiver certeza de que apenas o Javascript consumirá o JSON, prefiro transmitir
Date
objetos Javascript diretamente.O
ctime()
método nosdatetime
objetos retornará uma sequência que o objeto Data Javascript possa entender.O Javascript o utilizará como um literal de objeto, e você terá seu objeto Date incorporado.
fonte
.ctime()
é uma maneira MUITO ruim de passar informações de tempo,.isoformat()
é muito melhor. O que.ctime()
faz é jogar fora o fuso horário e o horário de verão como se eles não existissem. Essa função deve ser eliminada.Tarde no jogo ... :)
Uma solução muito simples é corrigir o padrão do módulo json. Por exemplo:
Agora, você pode usar json.dumps () como se ele sempre tivesse suporte em data e hora ...
Isso faz sentido se você precisar que essa extensão do módulo json sempre entre em ação e deseje não alterar a maneira como você ou outras pessoas usam a serialização json (no código existente ou não).
Observe que alguns podem considerar o patch de bibliotecas dessa maneira como uma má prática. Cuidados especiais devem ser tomados caso você queira estender seu aplicativo de mais de uma maneira - nesse caso, sugiro usar a solução por ramen ou JT e escolher a extensão json apropriada em cada caso.
fonte
None
. Você pode lançar uma exceção.Não há muito a acrescentar à resposta do wiki da comunidade, exceto o carimbo de data e hora !
Javascript usa o seguinte formato:
Lado do Python (para o
json.dumps
manipulador, veja as outras respostas):Se você deixar esse Z de fora, estruturas de front-end como angular não poderão exibir a data no fuso horário local do navegador:
fonte
No lado do python:
No lado do javascript:
onde os dados são resultado do python
fonte
Meu conselho é usar uma biblioteca. Existem vários disponíveis em pypi.org.
Eu uso este aqui, ele funciona bem: https://pypi.python.org/pypi/asjson
fonte
Aparentemente, o formato de data JSON "correto" (bem JavaScript) é 2012-04-23T18: 25: 43.511Z - UTC e "Z". Sem esse JavaScript, o fuso horário do navegador da Web será usado ao criar um objeto Date () a partir da string.
Por um horário "ingênuo" (o que o Python chama de horário sem fuso horário e isso pressupõe que é local), o abaixo forçará o fuso horário local para que possa ser convertido corretamente no UTC:
Por que isso é tão difícil.
fonte
Para a conversão de data do Python para JavaScript, o objeto de data precisa estar no formato ISO específico, ou seja, no formato ISO ou no número UNIX. Se o formato ISO não tiver algumas informações, você poderá converter para o número Unix com Date.parse primeiro. Além disso, o Date.parse também funciona com o React, enquanto o novo Date pode acionar uma exceção.
Caso você tenha um objeto DateTime sem milissegundos, é necessário considerar o seguinte. :
A data do exemplo pode ser igualmente uma variável no objeto result.data após uma chamada de API.
Para opções para exibir a data no formato desejado (por exemplo, para exibir dias úteis prolongados), consulte o documento MDN .
fonte