답변:
json.dumps에 'default'매개 변수를 추가하여이를 처리 할 수 있습니다.
date_handler = lambda obj: (
obj.isoformat()
if isinstance(obj, (datetime.datetime, datetime.date))
else None
)
json.dumps(datetime.datetime.now(), default=date_handler)
'"2010-04-20T20:08:21.634121"'
이는 ISO 8601 형식입니다.
보다 포괄적 인 기본 처리기 기능 :
def handler(obj):
if hasattr(obj, 'isoformat'):
return obj.isoformat()
elif isinstance(obj, ...):
return ...
else:
raise TypeError, 'Object of type %s with value of %s is not JSON serializable' % (type(obj), repr(obj))
업데이트 : 유형뿐만 아니라 값의 출력이 추가되었습니다.
업데이트 : 날짜도 처리
dthandler = lambda obj: obj.isoformat() if isinstance(obj, datetime) else json.JSONEncoder().default(obj)
언어 간 프로젝트의 경우 RfC 3339 날짜를 포함하는 문자열 이 가장 좋은 방법 이라는 것을 알았습니다 . RfC 3339 날짜는 다음과 같습니다.
1985-04-12T23:20:50.52Z
나는 대부분의 형식이 분명하다고 생각합니다. 다소 특이한 것은 끝에 "Z"일 수 있습니다. GMT / UTC를 나타냅니다. CEST (여름에는 독일)에 +02 : 00과 같은 시간대 오프셋을 추가 할 수도 있습니다. 개인적으로 모든 것이 표시 될 때까지 UTC로 유지하는 것을 선호합니다.
표시, 비교 및 저장을 위해 모든 언어에서 문자열 형식으로 남겨 둘 수 있습니다. 계산 날짜가 필요한 경우 대부분의 언어로 날짜를 기본 날짜 객체로 쉽게 변환 할 수 있습니다.
따라서 다음과 같이 JSON을 생성하십시오.
json.dump(datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ'))
불행히도 Javascript의 Date 생성자는 RfC 3339 문자열을 허용하지 않지만 인터넷 에는 많은 파서가 있습니다.
huTools.hujson 은 시간대를 올바르게 처리하면서 날짜 / 날짜 / 시간 객체를 포함하여 Python 코드에서 발생할 수있는 가장 일반적인 인코딩 문제를 처리하려고합니다.
datetime
datetime.isoformat () 및 by로 지원되며 기본적으로 객체를 문자열로 simplejson
덤프 datetime
합니다 isoformat
. 수동 strftime
해킹이 필요 없습니다 .
datetime
객체에서 isoformat
문자열로 자동 변환되지 않습니다 . 나를 위해, simplejson.dumps(datetime.now())
수확량TypeError: datetime.datetime(...) is not JSON serializable
json.dumps(datetime.datetime.now().isoformat())
마법이 일어나는 곳입니다.
나는 그것을 해결했다.
datetime.now ()로 만든 파이썬 datetime 객체 d 가 있다고 가정 해 봅시다 . 그 가치는 다음과 같습니다.
datetime.datetime(2011, 5, 25, 13, 34, 5, 787000)
ISO 8601 날짜 / 시간 문자열로 JSON에 직렬화 할 수 있습니다.
import json
json.dumps(d.isoformat())
예제 날짜 시간 객체는 다음과 같이 직렬화됩니다.
'"2011-05-25T13:34:05.787000"'
Javascript 레이어에서 수신 한이 값은 Date 객체를 생성 할 수 있습니다.
var d = new Date("2011-05-25T13:34:05.787000");
Javascript 1.8.5부터 Date 객체에는 표준 형식으로 문자열을 반환하는 toJSON 메서드가 있습니다. 위의 자바 스크립트 객체를 다시 JSON으로 직렬화하려면 명령은 다음과 같습니다.
d.toJSON()
어느 것이 당신에게 줄 것입니까?
'2011-05-25T20:34:05.787Z'
이 문자열은 일단 파이썬으로 수신되면 datetime 객체로 역 직렬화 될 수 있습니다.
datetime.strptime('2011-05-25T20:34:05.787Z', '%Y-%m-%dT%H:%M:%S.%fZ')
결과적으로 다음과 같은 날짜 / 시간 객체가 생성됩니다.
datetime.datetime(2011, 5, 25, 20, 34, 5, 787000)
를 사용하여 json
JSONEncoder를 서브 클래 싱하고 default () 메서드를 재정 의하여 고유 한 사용자 지정 serializer를 제공 할 수 있습니다.
import json
import datetime
class DateTimeJSONEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime.datetime):
return obj.isoformat()
else:
return super(DateTimeJSONEncoder, self).default(obj)
그런 다음 다음과 같이 호출 할 수 있습니다.
>>> DateTimeJSONEncoder().encode([datetime.datetime.now()])
'["2010-06-15T14:42:28"]'
obj.isoformat()
. 더 일반적인 dumps()
호출을 사용할 수도 있습니다 (예 indent
다음은 표준 라이브러리 json
모듈을 사용하여 datetime.datetime 및 datetime.date 객체를 재귀 적으로 인코딩하고 디코딩하기위한 매우 완벽한 솔루션입니다 . %f
datetime.datetime.strptime () 형식 문자열 의 형식 코드는 그 이후로만 지원 되므로 Python> = 2.6이 필요합니다 . Python 2.5 지원의 경우, %f
변환하기 전에 ISO 날짜 문자열에서 마이크로 초를 제거하고 제거하십시오. 물론 마이크로 초 정밀도는 느슨합니다. 표준 시간대 이름 또는 UTC 오프셋을 포함 할 수있는 다른 소스의 ISO 날짜 문자열과의 상호 운용성을 위해 변환 전에 날짜 문자열의 일부를 제거해야 할 수도 있습니다. ISO 날짜 문자열 (및 기타 여러 날짜 형식)에 대한 완전한 파서는 타사 dateutil 모듈을 참조하십시오 .
디코딩은 ISO 날짜 문자열이 JavaScript 리터럴 객체 표기법 또는 객체 내 중첩 구조의 값인 경우에만 작동합니다. 최상위 배열의 항목 인 ISO 날짜 문자열은 디코딩 되지 않습니다 .
즉,이 작동합니다 :
date = datetime.datetime.now()
>>> json = dumps(dict(foo='bar', innerdict=dict(date=date)))
>>> json
'{"innerdict": {"date": "2010-07-15T13:16:38.365579"}, "foo": "bar"}'
>>> loads(json)
{u'innerdict': {u'date': datetime.datetime(2010, 7, 15, 13, 16, 38, 365579)},
u'foo': u'bar'}
그리고 이것도 :
>>> json = dumps(['foo', 'bar', dict(date=date)])
>>> json
'["foo", "bar", {"date": "2010-07-15T13:16:38.365579"}]'
>>> loads(json)
[u'foo', u'bar', {u'date': datetime.datetime(2010, 7, 15, 13, 16, 38, 365579)}]
그러나 이것은 예상대로 작동하지 않습니다.
>>> json = dumps(['foo', 'bar', date])
>>> json
'["foo", "bar", "2010-07-15T13:16:38.365579"]'
>>> loads(json)
[u'foo', u'bar', u'2010-07-15T13:16:38.365579']
코드는 다음과 같습니다.
__all__ = ['dumps', 'loads']
import datetime
try:
import json
except ImportError:
import simplejson as json
class JSONDateTimeEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, (datetime.date, datetime.datetime)):
return obj.isoformat()
else:
return json.JSONEncoder.default(self, obj)
def datetime_decoder(d):
if isinstance(d, list):
pairs = enumerate(d)
elif isinstance(d, dict):
pairs = d.items()
result = []
for k,v in pairs:
if isinstance(v, basestring):
try:
# The %f format code is only supported in Python >= 2.6.
# For Python <= 2.5 strip off microseconds
# v = datetime.datetime.strptime(v.rsplit('.', 1)[0],
# '%Y-%m-%dT%H:%M:%S')
v = datetime.datetime.strptime(v, '%Y-%m-%dT%H:%M:%S.%f')
except ValueError:
try:
v = datetime.datetime.strptime(v, '%Y-%m-%d').date()
except ValueError:
pass
elif isinstance(v, (dict, list)):
v = datetime_decoder(v)
result.append((k, v))
if isinstance(d, list):
return [x[1] for x in result]
elif isinstance(d, dict):
return dict(result)
def dumps(obj):
return json.dumps(obj, cls=JSONDateTimeEncoder)
def loads(obj):
return json.loads(obj, object_hook=datetime_decoder)
if __name__ == '__main__':
mytimestamp = datetime.datetime.utcnow()
mydate = datetime.date.today()
data = dict(
foo = 42,
bar = [mytimestamp, mydate],
date = mydate,
timestamp = mytimestamp,
struct = dict(
date2 = mydate,
timestamp2 = mytimestamp
)
)
print repr(data)
jsonstring = dumps(data)
print jsonstring
print repr(loads(jsonstring))
datetime.datetime.utcnow().isoformat()[:-3]+"Z"
JSON.stringify ()가 자바 스크립트에서 생성하는 것과 정확히 같습니다
Javascript만이 JSON을 소비한다고 확신하는 경우 Javascript Date
객체를 직접 전달하는 것이 좋습니다.
객체 의 ctime()
메소드 datetime
는 Javascript Date 객체가 이해할 수있는 문자열을 반환합니다.
import datetime
date = datetime.datetime.today()
json = '{"mydate":new Date("%s")}' % date.ctime()
Javascript는이를 행복하게 객체 리터럴로 사용하며 Date 객체가 내장되어 있습니다.
.ctime()
시간 정보를 전달하는 매우 나쁜 방법 .isoformat()
이며 훨씬 좋습니다. 어떤 .ctime()
일은 그들이 존재하지 않는 것처럼 절약 시간대와 일광을 던져입니다. 이 기능은 종료되어야합니다.
게임에서 늦게 ... :)
아주 간단한 해결책은 json 모듈 기본값을 패치하는 것입니다. 예를 들면 다음과 같습니다.
import json
import datetime
json.JSONEncoder.default = lambda self,obj: (obj.isoformat() if isinstance(obj, datetime.datetime) else None)
이제 json.dumps () 를 항상 datetime을 지원 한 것처럼 사용할 수 있습니다 ...
json.dumps({'created':datetime.datetime.now()})
이것은 항상 확장하기 위해 json 모듈에 대한이 확장이 필요하고 귀하 또는 다른 사람들이 json 직렬화를 사용하는 방식 (기존 코드에서 또는 아닌)을 변경하지 않으려는 경우에 적합합니다.
어떤 사람들은 그런 방식으로 라이브러리 패치를 나쁜 습관으로 생각할 수 있습니다. 응용 프로그램을 여러 가지 방법으로 확장하려는 경우 특별한주의가 필요합니다.이 경우라면라면 또는 JT로 솔루션을 사용하고 각 경우에 적절한 json 확장을 선택하는 것이 좋습니다.
None
. 대신 예외를 던질 수도 있습니다.
타임 스탬프를 제외하고 커뮤니티 위키 답변에 추가하지 않아도됩니다 !
자바 스크립트는 다음 형식을 사용합니다.
new Date().toJSON() // "2016-01-08T19:00:00.123Z"
파이썬 측 ( json.dumps
핸들러에 대해서는 다른 답변을 참조하십시오) :
>>> from datetime import datetime
>>> d = datetime.strptime('2016-01-08T19:00:00.123Z', '%Y-%m-%dT%H:%M:%S.%fZ')
>>> d
datetime.datetime(2016, 1, 8, 19, 0, 0, 123000)
>>> d.isoformat() + 'Z'
'2016-01-08T19:00:00.123000Z'
Z를 제외하면 angular와 같은 프론트 엔드 프레임 워크는 브라우저 로컬 시간대로 날짜를 표시 할 수 없습니다.
> $filter('date')('2016-01-08T19:00:00.123000Z', 'yyyy-MM-dd HH:mm:ss')
"2016-01-08 20:00:00"
> $filter('date')('2016-01-08T19:00:00.123000', 'yyyy-MM-dd HH:mm:ss')
"2016-01-08 19:00:00"
내 조언은 도서관을 사용하는 것입니다. pypi.org에 여러 가지가 있습니다.
나는 이것을 사용한다, 그것은 잘 작동한다 : https://pypi.python.org/pypi/asjson
분명히 “올바른”JSON (잘 JavaScript) 날짜 형식 은 2012-04-23T18 : 25 : 43.511Z-UTC 및 "Z"입니다. 이 JavaScript가 없으면 문자열에서 Date () 객체를 만들 때 웹 브라우저의 현지 시간대를 사용합니다.
"순진한"시간 (파이썬이 시간대가없는 시간을 호출하고 이것이 현지인이라고 가정)의 경우 아래는 현지 시간대 를 강제 로 UTC로 올바르게 변환 할 수 있도록합니다.
def default(obj):
if hasattr(obj, "json") and callable(getattr(obj, "json")):
return obj.json()
if hasattr(obj, "isoformat") and callable(getattr(obj, "isoformat")):
# date/time objects
if not obj.utcoffset():
# add local timezone to "naive" local time
# /programming/2720319/python-figure-out-local-timezone
tzinfo = datetime.now(timezone.utc).astimezone().tzinfo
obj = obj.replace(tzinfo=tzinfo)
# convert to UTC
obj = obj.astimezone(timezone.utc)
# strip the UTC offset
obj = obj.replace(tzinfo=None)
return obj.isoformat() + "Z"
elif hasattr(obj, "__str__") and callable(getattr(obj, "__str__")):
return str(obj)
else:
print("obj:", obj)
raise TypeError(obj)
def dump(j, io):
json.dump(j, io, indent=2, default=default)
왜 이렇게 어려운가요?
Python에서 JavaScript로 날짜를 변환하려면 날짜 오브젝트가 특정 ISO 형식 (예 : ISO 형식 또는 UNIX 숫자)이어야합니다. ISO 형식에 정보가 부족하면 먼저 Date.parse를 사용하여 Unix 번호로 변환 할 수 있습니다. 또한 Date.parse는 React와 함께 작동하지만 새 Date는 예외를 트리거 할 수 있습니다.
밀리 초가없는 DateTime 객체가있는 경우 다음 사항을 고려해야합니다. :
var unixDate = Date.parse('2016-01-08T19:00:00')
var desiredDate = new Date(unixDate).toLocaleDateString();
예제 날짜는 API 호출 후 result.data 객체의 변수 일 수 있습니다.
원하는 형식으로 날짜를 표시하는 옵션 (예 : 긴 평일 표시)에 대해서는 MDN 문서를 확인하십시오 .