Я хочу отправить объект datetime.datetime в сериализованной форме из Python, используя JSON, и десериализовать в JavaScript, используя JSON. Каков наилучший способ сделать это?
javascript
python
json
Питер Мортенсен
источник
источник
Ответы:
Вы можете добавить параметр 'default' в json.dumps, чтобы обработать это:
Это формат ISO 8601 .
Более полная функция обработчика по умолчанию:
Обновление: добавлен вывод типа и значения.
Обновление: также обрабатывать дату
источник
dthandler = lambda obj: obj.isoformat() if isinstance(obj, datetime) else json.JSONEncoder().default(obj)
Для кросс-языковых проектов я обнаружил, что строки с датами RfC 3339 - лучший путь. Дата RfC 3339 выглядит следующим образом:
Я думаю, что большая часть формата очевидна. Единственной необычной вещью может быть буква «Z» в конце. Это означает GMT / UTC. Вы также можете добавить смещение часового пояса, например +02: 00 для CEST (Германия летом). Я лично предпочитаю хранить все в UTC, пока оно не отобразится.
Для отображения, сравнения и хранения вы можете оставить его в строковом формате на всех языках. Если вам нужна дата для расчетов, легко конвертировать ее обратно в объект родной даты на большинстве языков.
Так что сгенерируйте JSON так:
К сожалению, конструктор Date в Javascript не принимает строки RfC 3339, но в Интернете доступно много синтаксических анализаторов .
huTools.hujson пытается обработать наиболее распространенные проблемы кодирования, с которыми вы можете столкнуться в коде Python, включая объекты даты / даты и времени, при правильной обработке часовых поясов.
источник
datetime
datetime.isoformat (), так и bysimplejson
, который по умолчанию создает дампdatetime
объектов в видеisoformat
строк. Нет необходимости в ручномstrftime
взломе.datetime
объектов вisoformat
строку. Для меняsimplejson.dumps(datetime.now())
урожайностьTypeError: datetime.datetime(...) is not JSON serializable
json.dumps(datetime.datetime.now().isoformat())
Здесь происходит волшебство.Я решил это.
Допустим, у вас есть объект datetime Python, d , созданный с помощью datetime.now (). Его значение:
Вы можете сериализовать его в JSON в виде строки даты и времени ISO 8601:
Пример объекта datetime будет сериализован как:
Это значение, полученное в слое Javascript, может создать объект Date:
Начиная с Javascript 1.8.5, объекты Date имеют метод toJSON, который возвращает строку в стандартном формате. Поэтому для сериализации вышеуказанного объекта Javascript обратно в JSON команда должна быть:
Что бы дать вам:
Эта строка, однажды полученная в Python, может быть десериализована обратно в объект datetime:
Это приводит к следующему объекту datetime, который является тем же самым, с которого вы начали, и поэтому правильный:
источник
Используя
json
, вы можете создать подкласс JSONEncoder и переопределить метод default (), чтобы предоставить свои собственные сериализаторы:Затем вы можете назвать это так:
источник
obj.isoformat()
. Вы также можете использовать более распространенныйdumps()
вызов, который принимает другие полезные аргументы (напримерindent
): simplejson.dumps (myobj, cls = JSONEncoder, ...)Вот довольно полное решение для рекурсивного кодирования и декодирования объектов datetime.datetime и datetime.date с использованием стандартного библиотечного
json
модуля. Для этого требуется Python> = 2.6, поскольку%f
код формата в строке формата datetime.datetime.strptime () поддерживается только с тех пор. Для поддержки Python 2.5 удалите%f
и удалите микросекунды из строки даты ISO, прежде чем пытаться преобразовать ее, но, конечно, вы потеряете точность в микросекундах. Для совместимости со строками даты ISO из других источников, которые могут включать имя часового пояса или смещение UTC, вам также может потребоваться удалить некоторые части строки даты перед преобразованием. Для полного анализатора для строк даты ISO (и многих других форматов даты) см. Сторонний модуль dateutil .Декодирование работает только тогда, когда строки даты ISO являются значениями в буквенной нотации объектов JavaScript или во вложенных структурах внутри объекта. Строки даты ISO, которые являются элементами массива верхнего уровня, не будут декодированы.
Т.е. это работает:
И это тоже:
Но это не работает, как ожидалось:
Вот код:
источник
datetime.datetime.utcnow().isoformat()[:-3]+"Z"
это будет точно так же, как JSON.stringify () производит в javascriptЕсли вы уверены, что только Javascript будет использовать JSON, я предпочитаю передавать
Date
объекты Javascript напрямую.ctime()
Метод наdatetime
объектах возвращает строку , что дата объект Javascript может понять.Javascript с радостью будет использовать его в качестве литерала объекта, и у вас уже есть встроенный объект Date.
источник
.ctime()
это ОЧЕНЬ плохой способ передачи информации о времени,.isoformat()
гораздо лучше. Что.ctime()
отбрасывает часовой пояс и летнее время, как будто их не существует. Эта функция должна быть убита.Поздно в игре ... :)
Очень простое решение - установить исправление по умолчанию для модуля json. Например:
Теперь вы можете использовать json.dumps (), как если бы он всегда поддерживал datetime ...
Это имеет смысл, если вам требуется, чтобы это расширение модуля json всегда включалось и вы не хотели менять способ, которым вы или другие используете сериализацию json (в существующем коде или нет).
Обратите внимание, что некоторые могут расценивать исправление библиотек таким образом как плохую практику. Особая осторожность должна быть предпринята, если вы захотите расширить свое приложение более чем одним способом - в таком случае я предлагаю использовать решение по ramen или JT и выбрать правильное расширение json в каждом случае.
источник
None
. Вы можете вместо этого бросить исключение.Не так много, чтобы добавить в сообщество ответ вики, кроме отметки времени !
Javascript использует следующий формат:
Сторона Python (для
json.dumps
обработчика, см. Другие ответы):Если вы оставите этот Z вне, каркасы внешнего интерфейса, такие как angular, не смогут отображать дату в местном часовом поясе браузера:
источник
На стороне питона:
На стороне JavaScript:
где данные являются результатом Python
источник
Мой совет - использовать библиотеку. Есть несколько доступных на pypi.org.
Я использую этот, он работает хорошо: https://pypi.python.org/pypi/asjson
источник
Видимо, «правильным» форматом даты JSON (хорошо JavaScript) является 2012-04-23T18: 25: 43.511Z - UTC и «Z». Без этого JavaScript будет использовать локальный часовой пояс веб-браузера при создании объекта Date () из строки.
Для «наивного» времени (которое Python называет временем без часового пояса и предполагает, что оно является локальным), приведенное ниже будет принудительно устанавливать местный часовой пояс, чтобы затем его можно было правильно преобразовать в UTC:
Почему это так сложно.
источник
Для преобразования даты Python в JavaScript объект даты должен иметь определенный формат ISO, то есть формат ISO или номер UNIX. Если в формате ISO отсутствует некоторая информация, вы можете сначала преобразовать в число Unix с помощью Date.parse. Более того, Date.parse также работает с React, в то время как новый Date может вызвать исключение.
Если у вас есть объект DateTime без миллисекунд, необходимо учитывать следующее. :
Примерная дата может также быть переменной в объекте result.data после вызова API.
Для вариантов отображения даты в желаемом формате (например, для отображения длинных дней недели) ознакомьтесь с документом MDN .
источник