Je veux envoyer un objet datetime.datetime sous forme sérialisée à partir de Python en utilisant JSON et désérialiser en JavaScript en utilisant JSON. Quelle est la meilleure façon de procéder?
javascript
python
json
Peter Mortensen
la source
la source
Réponses:
Vous pouvez ajouter le paramètre 'default' à json.dumps pour gérer ceci:
Qui est ISO 8601 format .
Une fonction de gestionnaire par défaut plus complète:
Mise à jour: sortie ajoutée de type ainsi que de valeur.
Mise à jour: gérer également la date
la source
dthandler = lambda obj: obj.isoformat() if isinstance(obj, datetime) else json.JSONEncoder().default(obj)
Pour les projets multilingues , j'ai découvert que les chaînes contenant des dates RfC 3339 sont la meilleure solution. Une date RfC 3339 ressemble à ceci:
Je pense que la plupart du format est évident. La seule chose quelque peu inhabituelle peut être le "Z" à la fin. Il signifie GMT / UTC. Vous pouvez également ajouter un décalage de fuseau horaire comme +02: 00 pour CEST (Allemagne en été). Personnellement, je préfère tout garder en UTC jusqu'à ce qu'il s'affiche.
Pour l'affichage, les comparaisons et le stockage, vous pouvez le laisser sous forme de chaîne dans toutes les langues. Si vous avez besoin de la date pour les calculs, convertissez-la facilement en un objet de date natif dans la plupart des langues.
Générez donc le JSON comme ceci:
Malheureusement, le constructeur Date de Javascript n'accepte pas les chaînes RfC 3339 mais il existe de nombreux analyseurs disponibles sur Internet.
huTools.hujson essaie de gérer les problèmes d'encodage les plus courants que vous pourriez rencontrer dans le code Python, y compris les objets date / datetime tout en gérant correctement les fuseaux horaires.
la source
datetime
: datetime.isoformat () et parsimplejson
, qui videront lesdatetime
objets sous forme deisoformat
chaînes par défaut. Pas besoin destrftime
piratage manuel .datetime
objets enisoformat
chaîne. Pour moi, lessimplejson.dumps(datetime.now())
rendementsTypeError: datetime.datetime(...) is not JSON serializable
json.dumps(datetime.datetime.now().isoformat())
c'est là que la magie opère.Je l'ai résolu.
Disons que vous avez un objet datetime Python, d , créé avec datetime.now (). Sa valeur est:
Vous pouvez le sérialiser en JSON en tant que chaîne de date / heure ISO 8601:
L'exemple d'objet datetime serait sérialisé comme suit:
Cette valeur, une fois reçue dans la couche Javascript, peut construire un objet Date:
Depuis Javascript 1.8.5, les objets Date ont une méthode toJSON, qui retourne une chaîne dans un format standard. Pour sérialiser l'objet Javascript ci-dessus en JSON, la commande serait donc:
Ce qui vous donnerait:
Cette chaîne, une fois reçue en Python, pourrait être désérialisée en un objet datetime:
Cela se traduit par l'objet datetime suivant, qui est le même que celui avec lequel vous avez commencé et donc correct:
la source
À l'aide de
json
, vous pouvez sous-classer JSONEncoder et remplacer la méthode default () pour fournir vos propres sérialiseurs personnalisés:Ensuite, vous pouvez l'appeler comme ceci:
la source
obj.isoformat()
. Vous pouvez également utiliser l'appel le plus courantdumps()
, qui prend d'autres arguments utiles (commeindent
): simplejson.dumps (myobj, cls = JSONEncoder, ...)Voici une solution assez complète pour l'encodage et le décodage récursifs des objets datetime.datetime et datetime.date à l'aide du
json
module de bibliothèque standard . Cela nécessite Python> = 2.6 car le%f
code de format dans la chaîne de format datetime.datetime.strptime () n'est pris en charge que depuis lors. Pour la prise en charge de Python 2.5, supprimez le%f
et supprimez les microsecondes de la chaîne de date ISO avant d'essayer de le convertir, mais vous perdrez la précision des microsecondes, bien sûr. Pour l'interopérabilité avec les chaînes de date ISO d'autres sources, qui peuvent inclure un nom de fuseau horaire ou un décalage UTC, vous devrez peut-être également supprimer certaines parties de la chaîne de date avant la conversion. Pour un analyseur complet des chaînes de date ISO (et de nombreux autres formats de date), consultez le module de dateutil tiers .Le décodage ne fonctionne que lorsque les chaînes de date ISO sont des valeurs dans une notation d'objet littéral JavaScript ou dans des structures imbriquées dans un objet. Les chaînes de date ISO, qui sont des éléments d'un tableau de niveau supérieur, ne seront pas décodées.
C'est à dire que cela fonctionne:
Et cela aussi:
Mais cela ne fonctionne pas comme prévu:
Voici le code:
la source
datetime.datetime.utcnow().isoformat()[:-3]+"Z"
elle sera exactement comme ce que JSON.stringify () produit en javascriptSi vous êtes certain que seul Javascript consommera le JSON, je préfère passer
Date
directement les objets Javascript .La
ctime()
méthode sur lesdatetime
objets renverra une chaîne que l'objet Date Javascript peut comprendre.Javascript sera heureux de l'utiliser comme un littéral d'objet, et vous avez votre objet Date intégré.
la source
.ctime()
est un TRÈS mauvais moyen de transmettre des informations sur le temps,.isoformat()
c'est beaucoup mieux. Ce.ctime()
qui est de jeter le fuseau horaire et l'heure d'été comme s'ils n'existaient pas. Cette fonction devrait être supprimée.Tard dans le jeu ... :)
Une solution très simple consiste à patcher le module json par défaut. Par exemple:
Maintenant, vous pouvez utiliser json.dumps () comme s'il avait toujours pris en charge datetime ...
Cela a du sens si vous avez besoin que cette extension du module json démarre toujours et que vous ne vouliez pas changer la façon dont vous ou d'autres utilisez la sérialisation json (dans le code existant ou non).
Notez que certains peuvent considérer les correctifs de bibliothèques de cette manière comme une mauvaise pratique. Une attention particulière doit être portée au cas où vous souhaiteriez étendre votre application de plusieurs manières - dans ce cas, je suggère d'utiliser la solution par ramen ou JT et de choisir l'extension json appropriée dans chaque cas.
la source
None
. Vous voudrez peut-être lever une exception à la place.Pas grand chose à ajouter à la réponse du wiki communautaire, à l'exception de l' horodatage !
Javascript utilise le format suivant:
Côté Python (pour le
json.dumps
gestionnaire, voir les autres réponses):Si vous omettez ce Z, les frameworks frontaux comme angular ne peuvent pas afficher la date dans le fuseau horaire local du navigateur:
la source
Côté python:
Côté javascript:
où les données proviennent de python
la source
Mon conseil est d'utiliser une bibliothèque. Il y en a plusieurs disponibles sur pypi.org.
J'utilise celui-ci, ça marche bien: https://pypi.python.org/pypi/asjson
la source
Apparemment, le «bon» format de date JSON (bien JavaScript) est 2012-04-23T18: 25: 43.511Z - UTC et «Z». Sans cela, JavaScript utilisera le fuseau horaire local du navigateur Web lors de la création d'un objet Date () à partir de la chaîne.
Pour un temps "naïf" (ce que Python appelle un temps sans fuseau horaire et cela suppose qu'il est local), le ci-dessous forcera le fuseau horaire local afin qu'il puisse ensuite être correctement converti en UTC:
Pourquoi est-ce si difficile.
la source
Pour la conversion de date Python en JavaScript, l'objet date doit être au format ISO spécifique, c'est-à-dire au format ISO ou au numéro UNIX. Si le format ISO manque d'informations, vous pouvez d'abord convertir au numéro Unix avec Date.parse. De plus, Date.parse fonctionne également avec React tandis que la nouvelle Date peut déclencher une exception.
Si vous disposez d'un objet DateTime sans millisecondes, les éléments suivants doivent être pris en compte. :
L'exemple de date peut également être une variable dans l'objet result.data après un appel d'API.
Pour les options pour afficher la date dans le format souhaité (par exemple pour afficher les longs jours de la semaine), consultez le document MDN .
la source