कैसे "datetime.datetime नहीं JSON अनुक्रमिक" पर काबू पाने के लिए?


739

मेरे पास एक बुनियादी तानाशाही इस प्रकार है:

sample = {}
sample['title'] = "String"
sample['somedate'] = somedatetimehere

जब मैं करने की कोशिश करता jsonify(sample)हूं:

TypeError: datetime.datetime(2012, 8, 8, 21, 46, 24, 862000) is not JSON serializable

मैं ऐसा क्या कर सकता हूं जिससे मेरा शब्दकोश नमूना ऊपर की त्रुटि को दूर कर सके?

नोट: हालांकि यह प्रासंगिक नहीं हो सकता है, लेकिन mongodbजहां से मैं प्रिंट आउट करता हूं , वहां से रिकॉर्ड की पुनर्प्राप्ति से शब्दकोश उत्पन्न होते हैं str(sample['somedate']), आउटपुट है 2012-08-08 21:46:24.862000


1
क्या यह विशेष रूप से सामान्य रूप से अजगर है, या संभवतः django?
jdi

1
यह तकनीकी रूप से विशेष रूप से अजगर है, मैं django का उपयोग नहीं कर रहा हूं, लेकिन मोंगोडब से रिकॉर्ड प्राप्त कर रहा हूं।
रोलैंडो


मैं मोंगोएंगाइन का उपयोग कर रहा हूं, लेकिन अगर पाइमोंगो के पास इसके आसपास या इस पर काबू पाने के बेहतर तरीके हैं, तो कृपया बताएं।
रोलैंडो

3
जुड़ा हुआ प्रश्न अनिवार्य रूप से आपको बता रहा है कि आप डेटाइम ऑब्जेक्ट को क्रमबद्ध करने की कोशिश न करें, बल्कि इसे सीरीज़ करने से पहले आम आईएसओ प्रारूप में स्ट्रिंग में परिवर्तित करें।
थॉमस केली

जवाबों:


377

2018 के लिए अपडेट किया गया

मूल उत्तर ने जिस तरह से MongoDB "तिथि" फ़ील्ड को इस रूप में दर्शाया था:

{"$date": 1506816000000}

यदि आप जीन्सdatetime को क्रमबद्ध करने के लिए एक सामान्य पायथन समाधान चाहते हैं , तो त्वरित समाधान के लिए @jjmontes के उत्तर की जांच करें जिसके लिए कोई निर्भरता की आवश्यकता नहीं है।


जैसा कि आप mongoengine (टिप्पणियों के अनुसार) का उपयोग कर रहे हैं और pymongo एक निर्भरता है, pymongo ने json क्रमांकन के साथ मदद करने के लिए उपयोगिताओं का निर्माण किया है:
http://api.mongodb.org/python/1.10.1.1_api/bson/json_util.html

उदाहरण उपयोग (क्रमांकन):

from bson import json_util
import json

json.dumps(anObject, default=json_util.default)

उदाहरण उपयोग (डीरियलाइज़ेशन):

json.loads(aJsonString, object_hook=json_util.object_hook)

Django

Django एक मूल DjangoJSONEncoderधारावाहिक प्रदान करता है जो इस तरह के ठीक से व्यवहार करता है ।

Https://docs.djangoproject.com/en/dev/topics/serialization/#djangojsonencoder देखें

from django.core.serializers.json import DjangoJSONEncoder

return json.dumps(
  item,
  sort_keys=True,
  indent=1,
  cls=DjangoJSONEncoder
)

एक अंतर जो मैंने इस तरह से DjangoJSONEncoderएक कस्टम के बीच और उपयोग किया है default:

import datetime
import json

def default(o):
    if isinstance(o, (datetime.date, datetime.datetime)):
        return o.isoformat()

return json.dumps(
  item,
  sort_keys=True,
  indent=1,
  default=default
)

क्या Django डेटा का एक छोटा सा हिस्सा है:

 "last_login": "2018-08-03T10:51:42.990", # DjangoJSONEncoder 
 "last_login": "2018-08-03T10:51:42.990239", # default

तो, आपको कुछ मामलों में इससे सावधान रहने की आवश्यकता हो सकती है।


3
क्या कई पुस्तकालयों को मिलाया जाना अच्छा है / बुरा है अर्थात डॉक्स और पाइमॉन्गो को क्वेरी / रिट्रीवल के लिए सम्मिलित करने के लिए मोंगोन्जाइन होना?
रोलैंडो

इसका बुरा व्यवहार नहीं है, यह सिर्फ आपके मुख्य पुस्तकालय द्वारा उपयोग किए जाने वाले पुस्तकालयों पर निर्भरता का अर्थ है। यदि आप मूंगोइन से जो कुछ भी चाहते हैं, उसे पूरा नहीं कर सकते हैं, तो आप पाइमोंगो को छोड़ देते हैं। इसके साथ भी ऐसा ही है Django MongoDB। बाद में, आप बैकेंड अज्ञेय राज्य को बनाए रखने के लिए django ORM के भीतर रहने की कोशिश करेंगे। लेकिन कभी-कभी आप वह नहीं कर पाते हैं, जिसकी आपको अमूर्तता में आवश्यकता होती है, इसलिए आप एक परत छोड़ देते हैं। इस स्थिति में, यह आपकी समस्या के लिए पूरी तरह से असंबंधित है क्योंकि आप केवल JSON प्रारूप के साथ उपयोगिता विधियों का उपयोग कर रहे हैं।
जीडी

मैं इसे फ्लास्क के साथ आज़मा रहा हूं और ऐसा प्रतीत होता है कि json.dump का उपयोग करके, मैं इसके चारों ओर एक jsonify () आवरण को डालने में असमर्थ हूं, ताकि यह एप्लिकेशन / json में वापस आ जाए। रिटर्न jsonify करने की कोशिश (json.dumps (नमूना, डिफ़ॉल्ट = json_util.default))
Rolando

2
@amit सिंटैक्स को याद रखने के बारे में इतना नहीं है, क्योंकि यह प्रलेखन पढ़ने में अच्छा है और मुझे फिर से इसे पुनः प्राप्त करने की आवश्यकता है, जहां पहचानने के लिए मेरे सिर में पर्याप्त जानकारी संग्रहीत है। इस मामले में, कोई भी कह सकता है "ओह एक कस्टम ऑब्जेक्ट
जसन के

2
@guyskk मैंने 5 साल पहले जब से यह लिखा है तब से मैंने bjson या mongo में बदलावों पर नज़र नहीं रखी है। लेकिन अगर आप डेटाइम के क्रमांकन पर नियंत्रण चाहते हैं, तो आपको अपने स्वयं के डिफ़ॉल्ट हैंडलर फंक्शन को लिखने की आवश्यकता है, जैसा कि उत्तर में दिया गया है
jgbarah

615

मेरा त्वरित और गंदा JSON डंप है जो दिनांक और सब कुछ खाता है:

json.dumps(my_dictionary, indent=4, sort_keys=True, default=str)

13
यह भयानक है, लेकिन दुर्भाग्य से मुझे समझ नहीं आया कि क्या हुआ? क्या कोई इसका उत्तर समझा सकता है?
किशोर पवार

61
@ KishorPawar: defaultएक ऐसा फंक्शन है जो उन वस्तुओं पर लागू होता है जो क्रमबद्ध नहीं हैं। इस मामले में यह है str, इसलिए यह बस सब कुछ धर्मान्तरित करता है जिसे यह तार नहीं जानता है। जो क्रमबद्धता के लिए बहुत अच्छा है, लेकिन इतना महान नहीं है जब deserializing (इसलिए "त्वरित और गंदा") जैसा कि कुछ भी चेतावनी के बिना स्ट्रिंग-ified हो सकता है, जैसे कि एक फ़ंक्शन या संख्यात्मक सरणी।
मार्क

1
@ मर्क कमाल। धन्यवाद। उपयोगी जब आप उन गैर-क्रमिक मानों के प्रकार जानते हैं जैसे दिनांक।
किशोर पवार

2
मैंने अपना सारा जीवन यह न जाने क्यों दिया। :)
अरेल

1
@jjmontes, सब कुछ के लिए काम नहीं करता है, जैसे , json.dumps({():1,type(None):2},default=str)उठाता है TypeError, टाइप या टपल नहीं हो सकता।
अलंकालविटि

443

अन्य उत्तरों पर निर्माण, एक विशिष्ट धारावाहिक के आधार पर एक सरल समाधान जो बस तार datetime.datetimeऔर datetime.dateवस्तुओं को कंवर्ट करता है।

from datetime import date, datetime

def json_serial(obj):
    """JSON serializer for objects not serializable by default json code"""

    if isinstance(obj, (datetime, date)):
        return obj.isoformat()
    raise TypeError ("Type %s not serializable" % type(obj))

जैसा कि देखा गया है, कोड सिर्फ यह पता लगाने के लिए जांचता है कि ऑब्जेक्ट क्लास का है datetime.datetimeया नहीं datetime.date, और फिर .isoformat()आईएसओ 8601 फॉर्मेट, YYYY-MM-DDTHH: MM: SS (जो आसानी से जावास्क्रिप्ट पर आसानी से डिकोड हो जाता है) के अनुसार, इसका क्रमबद्ध संस्करण तैयार करता है। )। यदि अधिक जटिल क्रमबद्ध अभ्यावेदन मांगे गए हैं, तो str () के बजाय अन्य कोड का उपयोग किया जा सकता है (उदाहरण के लिए इस प्रश्न के अन्य उत्तर देखें)। कोड एक अपवाद को बढ़ाकर समाप्त होता है, उस मामले से निपटने के लिए जिसे गैर-धारावाहिक प्रकार के साथ कहा जाता है।

इस json_serial फ़ंक्शन का उपयोग निम्नानुसार किया जा सकता है:

from datetime import datetime
from json import dumps

print dumps(datetime.now(), default=json_serial)

Json.dumps के डिफ़ॉल्ट पैरामीटर कैसे काम करता है, इसके बारे में विवरण , json मॉड्यूल प्रलेखन के खंड मूल उपयोग में पाया जा सकता है ।


5
हाँ सही उत्तर, अधिक सुंदर आयात डेटाटाइम और यदि आइंस्टीन (obj, डेटाटाइम.टाइमटाइम), तो मैंने कई बार खो दिया क्योंकि डेटाइम आयात से आयात नहीं किया गया है, वैसे भी धन्यवाद
सेरजियो

12
लेकिन यह कैसे सही प्रकार के साथ यह deserialise करने के लिए, यह व्याख्या नहीं करता है?
ब्लूट्रिन

2
नहीं, @BlueTrin, उस बारे में कुछ नहीं कहा गया। मेरे मामले में, मैं जावास्क्रिप्ट में डिसरिज़लाइज़ कर रहा हूं, जो बॉक्स से बाहर काम करता है।
jgbarah

1
यह अनपेक्षित व्यवहार का कारण बनेगा, अगर json मॉड्यूल कभी भी डेटाइम ऑब्जेक्ट के क्रमांकन को अद्यतन करने के लिए अद्यतन करता है।
जस्टिन

1
@serg लेकिन UTC को बार-बार परिवर्तित करना एकीकृत होगा 01:00:00+01:00और 02:00:00+00:00जो संदर्भ के आधार पर समान नहीं होना चाहिए। वे पाठ्यक्रम के समय में एक ही बिंदु को संदर्भित करते हैं, लेकिन ऑफसेट मूल्य का एक प्रासंगिक पहलू हो सकता है।
अल्फ सिप

211

मुझे अभी इस समस्या का सामना करना पड़ा है और मेरा समाधान उपवर्ग के लिए है json.JSONEncoder:

from datetime import datetime
import json

class DateTimeEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, datetime):
            return o.isoformat()

        return json.JSONEncoder.default(self, o)

: आपके कॉल में की तरह कुछ करना मैं ऊपर जवाब में से एक से मिला है।json.dumps(yourobj, cls=DateTimeEncoder).isoformat()


22
एक कस्टम JSONEncoder को लागू करने के लिए जाने का कारण उचित रास्ता होना चाहिए
3k-

25
न केवल यह शीर्ष उत्तर होना चाहिए, यह नियमित जोंस एनकोडर का हिस्सा होना चाहिए। यदि केवल डिकोडिंग कम अस्पष्ट था ..
Joost

4
Django का उपयोग करने वालों के लिए, देखें DjangoJSONEncoderdocs.djangoproject.com/en/dev/topics/serialization/…
एस। किर्बी

4
सुपर सहायक। अंतिम पंक्ति हो सकती हैreturn super(DateTimeEncoder, self).default(o)
बॉब स्टीन

16
पायथन 3 के साथ अंतिम पंक्ति और भी सरल है:return super().default(o)
ariddell

124

दिनांक को एक स्ट्रिंग में बदलें

sample['somedate'] = str( datetime.utcnow() )

10
और मैं इसे पायथन में कैसे चित्रित कर सकता हूं?
वॉबमेन

62
समस्या यह है कि यदि आपके पास डेटा संरचना में गहराई से एम्बेडेड कई डेटाटाइम ऑब्जेक्ट हैं, या वे यादृच्छिक हैं। यह एक विश्वसनीय तरीका नहीं है।
rebs

3
deserialize करने के लिए oDate = datetime.datetime.strptime(sDate, '%Y-%m-%d %H:%M:%S.%f'):। से प्राप्त प्रारूप: docs.python.org/2/library/datetime.html
रोमन

13
डाउनवोट किया गया क्योंकि यह समय क्षेत्र की जानकारी को नजरअंदाज करता है। .now()यह इंगित करने के बिना, स्थानीय समय का उपयोग करने वाले ध्यान रखें । कम से कम .utcnow()इस्तेमाल किया जाना चाहिए (और तब +0000 या जेड जोड़ा गया)
डैनियल एफ

1
@DanielF At least .utcnow() should be usedबिल्कुल अनुशंसित नहीं है, इसमें datetime.now(timezone.utc)चेतावनी देखें: docs.python.org/3.8/library/…
टोरेनो96

79

दूसरों के लिए, जिन्हें इसके लिए पाइमॉन्गो लाइब्रेरी का उपयोग करने की आवश्यकता नहीं है या नहीं चाहते हैं .. आप इस छोटे से स्निपेट के साथ आसानी से डेटाइम JSON रूपांतरण प्राप्त कर सकते हैं:

def default(obj):
    """Default JSON serializer."""
    import calendar, datetime

    if isinstance(obj, datetime.datetime):
        if obj.utcoffset() is not None:
            obj = obj - obj.utcoffset()
        millis = int(
            calendar.timegm(obj.timetuple()) * 1000 +
            obj.microsecond / 1000
        )
        return millis
    raise TypeError('Not sure how to serialize %s' % (obj,))

फिर इसे इस तरह उपयोग करें:

import datetime, json
print json.dumps(datetime.datetime.now(), default=default)

उत्पादन: 

'1365091796124'

1
millis=अगर बयान के अंदर नहीं किया जाना चाहिए ? आईएसओ प्रारूप प्राप्त करने के लिए str (obj) का उपयोग करना शायद बेहतर होगा जो मुझे लगता है कि अधिक सामान्य है।
rebs

आप क्यों चाहते हैं कि यह इंडेंट हो? यह स्निपेट काम करता है और परिणामी आउटपुट को जावास्क्रिप्ट से आसानी से deserialized / पार्स किया जा सकता है।
जे टेलर

5
क्योंकि
ओब्ज

2
आपका उदाहरण गलत है यदि स्थानीय समय क्षेत्र में गैर-शून्य यूटीसी ऑफसेट (उनमें से अधिकांश) हैं। datetime.now()स्थानीय समय लौटाता है (एक भोली-भाली वस्तु के रूप में) लेकिन आपका कोड मानता है कि objअगर यह समय-अवगत नहीं है तो UTC में है। datetime.utcnow()इसके बजाय उपयोग करें ।
jfs

1
यदि dj.pythth.org.org/2/library/json.html#basic-usage पर पायथन डॉक्यूमेंटेशन की सिफारिश के अनुसार गैर मान्यता प्राप्त है, तो इसे एक प्रकार की त्रुटि बढ़ाने के लिए समायोजित किया गया है ।
जे टेलर टेलर

40

यहाँ मेरा समाधान है:

# -*- coding: utf-8 -*-
import json


class DatetimeEncoder(json.JSONEncoder):
    def default(self, obj):
        try:
            return super(DatetimeEncoder, obj).default(obj)
        except TypeError:
            return str(obj)

तो आप इसे इस तरह से उपयोग कर सकते हैं:

json.dumps(dictionnary, cls=DatetimeEncoder)

इस बात से सहमत। बहुत बेहतर, कम से कम मोंगोडब संदर्भ से बाहर। आप isinstance(obj, datetime.datetime)TypeError के भीतर कर सकते हैं , हैंडल करने के लिए और प्रकार जोड़ सकते हैं और साथ में समाप्त कर str(obj)सकते हैं repr(obj)। और आपके सभी डंप इस विशेष वर्ग को इंगित कर सकते हैं।
JL Peyret

@ नैटिम यह समाधान सबसे अच्छा है। +1
सौविक रे

20

मेरे पास एक समान मुद्दे के साथ एक आवेदन है; मेरा दृष्टिकोण एक 6-आइटम सूची (वर्ष, माह, दिन, घंटा, मिनट, सेकंड) के रूप में डेटाटाइम मान को JSONize करना था; आप 7-आइटम सूची के रूप में माइक्रोसेकंड में जा सकते हैं, लेकिन मुझे इसकी कोई आवश्यकता नहीं थी:

class DateTimeEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime.datetime):
            encoded_object = list(obj.timetuple())[0:6]
        else:
            encoded_object =json.JSONEncoder.default(self, obj)
        return encoded_object

sample = {}
sample['title'] = "String"
sample['somedate'] = datetime.datetime.now()

print sample
print json.dumps(sample, cls=DateTimeEncoder)

पैदा करता है:

{'somedate': datetime.datetime(2013, 8, 1, 16, 22, 45, 890000), 'title': 'String'}
{"somedate": [2013, 8, 1, 16, 22, 45], "title": "String"}

काम करने के लिए समय बचा लिया गया है, तो काम करने में विफल रहता है datetime.utcnow ()
saurshaz

1
आप datetime.utcnow () के साथ क्या त्रुटि देख रहे हैं? यह मेरे लिए ठीक काम करता है।
कोडिंगैट्टी

17

मेरा समाधान (कम वाचालता के साथ, मुझे लगता है):

def default(o):
    if type(o) is datetime.date or type(o) is datetime.datetime:
        return o.isoformat()

def jsondumps(o):
    return json.dumps(o, default=default)

तो के jsondumpsबजाय का उपयोग करें json.dumps। यह प्रिंट होगा:

>>> jsondumps({'today': datetime.date.today()})
'{"today": "2013-07-30"}'

मैं चाहता हूं, बाद में आप defaultविधि के एक साधारण मोड़ के साथ अन्य विशेष मामलों को इसमें जोड़ सकते हैं । उदाहरण:

def default(o):
    if type(o) is datetime.date or type(o) is datetime.datetime:
        return o.isoformat()
    if type(o) is decimal.Decimal:
        return float(o)

1
आपको आइंस्टीन (ओ, (datetime.date, datetime.datetime,)) का उपयोग करना चाहिए। संभवत: डेटटाइम भी शामिल करने के लिए चोट नहीं पहुंचेगी।
rebs

मुझे नहीं लगता कि यह अब एक अच्छा समाधान है। संभवतः रूपांतरणों को अधिक विशेषाधिकार प्राप्त स्थान - और भी अधिक समझने योग्य स्थान - अपने कोड में लेना चाहिए, इसलिए आप जानते हैं कि जब आप डेटाबेस में चीजों को डालते हैं या आप जो कुछ भी करते हैं, उसके बदले में आप क्या कर रहे हैं। पारदर्शी समारोह। लेकिन मुझे नहीं पता।
फिएटजैफ

1
JSON बाद में प्रसंस्करण के लिए क्रमबद्ध डेटा के लिए अच्छा है। आप शायद नहीं जानते कि डेटा क्या है। और आपको इसकी आवश्यकता नहीं होनी चाहिए सीरियल JSON सिर्फ काम करना चाहिए। जैसे यूनिकोड को एससीआई में परिवर्तित करना चाहिए। अस्पष्ट कार्यों के बिना ऐसा करने में पायथन की असमर्थता इसे उपयोग करने के लिए कष्टप्रद बनाती है। डेटाबेस सत्यापन एक अलग मुद्दा IMO है।
rebs

नहीं, यह "सिर्फ काम" नहीं होना चाहिए। यदि आप नहीं जानते कि क्रमांकन कैसे हुआ और बाद में किसी अन्य प्रोग्राम / भाषा से डेटा एक्सेस करना पड़ता है, तो आप खो गए हैं।
फिएटजैफ

2
JSON का उपयोग आमतौर पर स्ट्रिंग्स, इनट्स, फ्लोट्स, तिथियों के लिए किया जाता है (मुझे यकीन है कि अन्य मुद्रा, तापमान, आमतौर पर भी उपयोग करते हैं)। लेकिन डेटाइम मानक पुस्तकालय का हिस्सा है और इसे डी / क्रमांकन का समर्थन करना चाहिए। यदि यह इस प्रश्न के लिए नहीं था, तो मैं अभी भी तारीखों के लिए मैन्युअल रूप से अपने अविश्वसनीय रूप से जटिल
जॉन्स ब्लॉब्स

16

यह क्यू समय और समय को फिर से दोहराता है - जैसन मॉड्यूल को पैच करने का एक सरल तरीका है कि क्रमबद्धता डेटाइम का समर्थन करेगी।

import json
import datetime

json.JSONEncoder.default = lambda self,obj: (obj.isoformat() if isinstance(obj, datetime.datetime) else None)

जैसा कि आप हमेशा करते हैं, इस प्रकार जसन क्रमांकन का उपयोग करें - इस बार डेटाइम के साथ इसोफ़ॉर्मेट के रूप में क्रमबद्ध होने के साथ।

json.dumps({'created':datetime.datetime.now()})

परिणाम: '' "सृजित": "2015-08-26T14: 21: 31.853855"}

अधिक विवरण और सावधानी के कुछ शब्दों को देखें: StackOverflow: पायथन और जावास्क्रिप्ट के बीच JSON डेटाइम


बंदर पैच FTW। निस्संदेह बात यह है कि यह आपके पूरे आवेदन में जसन मॉड्यूल के व्यवहार को संशोधित करता है, जो एक बड़े आवेदन में दूसरों को आश्चर्यचकित कर सकता है, इसलिए आमतौर पर देखभाल इम्हो के साथ उपयोग किया जाना चाहिए।
जाप वेरस्टीघ

15

Json.dumps विधि डिफ़ॉल्ट नामक एक वैकल्पिक पैरामीटर को स्वीकार कर सकती है जो कि एक फ़ंक्शन होने की उम्मीद है। हर बार JSON एक ऐसे मूल्य को परिवर्तित करने की कोशिश करता है जो यह नहीं जानता कि इसे कैसे परिवर्तित किया जाए, हम इसे उस फ़ंक्शन को कहेंगे जो हमने इसे पारित किया था। फ़ंक्शन को ऑब्जेक्ट को प्रश्न में प्राप्त होगा, और ऑब्जेक्ट के JSON प्रतिनिधित्व को वापस करने की उम्मीद है।

def myconverter(o):
 if isinstance(o, datetime.datetime):
    return o.__str__()

print(json.dumps(d, default = myconverter)) 

14

यदि आप python3.7 का उपयोग कर रहे हैं, तो सबसे अच्छा समाधान उपयोग कर रहा है datetime.isoformat()और datetime.fromisoformat(); वे भोले और जागरूक दोनों datetimeवस्तुओं के साथ काम करते हैं:

#!/usr/bin/env python3.7

from datetime import datetime
from datetime import timezone
from datetime import timedelta
import json

def default(obj):
    if isinstance(obj, datetime):
        return { '_isoformat': obj.isoformat() }
    return super().default(obj)

def object_hook(obj):
    _isoformat = obj.get('_isoformat')
    if _isoformat is not None:
        return datetime.fromisoformat(_isoformat)
    return obj

if __name__ == '__main__':
    #d = { 'now': datetime(2000, 1, 1) }
    d = { 'now': datetime(2000, 1, 1, tzinfo=timezone(timedelta(hours=-8))) }
    s = json.dumps(d, default=default)
    print(s)
    print(d == json.loads(s, object_hook=object_hook))

उत्पादन:

{"now": {"_isoformat": "2000-01-01T00:00:00-08:00"}}
True

यदि आप python3.6 या उससे नीचे का उपयोग कर रहे हैं, और आप केवल समय मान (समयक्षेत्र नहीं) का ध्यान रखते हैं, तो आप उपयोग कर सकते हैं datetime.timestamp()और datetime.fromtimestamp()इसके बजाय;

यदि आप python3.6 या नीचे का उपयोग कर रहे हैं, और आप समयक्षेत्र के बारे में परवाह करते हैं, तो आप इसे प्राप्त कर सकते हैं datetime.tzinfo , लेकिन आपको इस क्षेत्र को अपने आप से क्रमबद्ध करना होगा; ऐसा करने का सबसे आसान तरीका _tzinfoक्रमबद्ध ऑब्जेक्ट में एक और फ़ील्ड जोड़ना है ;

अंत में, इन सभी उदाहरणों में पूर्वापेक्षाओं से सावधान रहें;



11

आपको .strftime()विधि पर .datetime.now()विधि का उपयोग इसे धारावाहिक बनाने की विधि के रूप में करना चाहिए ।

यहाँ एक उदाहरण है:

from datetime import datetime

time_dict = {'time': datetime.now().strftime('%Y-%m-%dT%H:%M:%S')}
sample_dict = {'a': 1, 'b': 2}
sample_dict.update(time_dict)
sample_dict

आउटपुट:

Out[0]: {'a': 1, 'b': 2, 'time': '2017-10-31T15:16:30'}

10

यहाँ आने के लिए एक सरल समाधान है "डेटाइम नहीं JSON serializable" समस्या।

enco = lambda obj: (
    obj.isoformat()
    if isinstance(obj, datetime.datetime)
    or isinstance(obj, datetime.date)
    else None
)

json.dumps({'date': datetime.datetime.now()}, default=enco)

आउटपुट: -> {"तिथि": "2015-12-16T04: 48: 20.024609"}


8

आप के clsपैरामीटर के साथ एक कस्टम एनकोडर वर्ग की आपूर्ति करनी है json.dumpsडॉक्स से उद्धृत करने के लिए :

>>> import json
>>> class ComplexEncoder(json.JSONEncoder):
...     def default(self, obj):
...         if isinstance(obj, complex):
...             return [obj.real, obj.imag]
...         return json.JSONEncoder.default(self, obj)
...
>>> dumps(2 + 1j, cls=ComplexEncoder)
'[2.0, 1.0]'
>>> ComplexEncoder().encode(2 + 1j)
'[2.0, 1.0]'
>>> list(ComplexEncoder().iterencode(2 + 1j))
['[', '2.0', ', ', '1.0', ']']

यह उदाहरण के रूप में जटिल संख्याओं का उपयोग करता है, लेकिन आप आसानी से तिथियों को एन्कोड करने के लिए आसानी से एक क्लास बना सकते हैं (सिवाय मुझे लगता है कि JSON तारीखों के बारे में थोड़ा फजी है)


5

ऐसा करने का सबसे सरल तरीका उस तानाशाही के हिस्से को बदलना है जो डेटोफ़ॉर्म प्रारूप में इसोफ़ॉर्मैट में है। यह मूल्य प्रभावी रूप से isoformat में एक स्ट्रिंग होगा जो कि json के साथ ठीक है।

v_dict = version.dict()
v_dict['created_at'] = v_dict['created_at'].isoformat()

5

वास्तव में यह काफी सरल है। यदि आपको अक्सर तारीखों को क्रमबद्ध करने की आवश्यकता होती है, तो उनके साथ तार के रूप में काम करें। जरूरत पड़ने पर आप इन्हें आसानी से डेटाइम ऑब्जेक्ट के रूप में बदल सकते हैं।

यदि आपको ज्यादातर डेटाइम ऑब्जेक्ट के रूप में काम करने की आवश्यकता है, तो उन्हें क्रमबद्ध करने से पहले स्ट्रिंग के रूप में परिवर्तित करें।

import json, datetime

date = str(datetime.datetime.now())
print(json.dumps(date))
"2018-12-01 15:44:34.409085"
print(type(date))
<class 'str'>

datetime_obj = datetime.datetime.strptime(date, '%Y-%m-%d %H:%M:%S.%f')
print(datetime_obj)
2018-12-01 15:44:34.409085
print(type(datetime_obj))
<class 'datetime.datetime'>

जैसा कि आप देख सकते हैं, आउटपुट दोनों मामलों में समान है। केवल प्रकार अलग है।


3

यदि आप दृश्य में परिणाम का उपयोग कर रहे हैं, तो उचित प्रतिक्रिया वापस करना सुनिश्चित करें। एपीआई के अनुसार, jsonify निम्नलिखित करता है:

अनुप्रयोग / json mimetype के साथ दिए गए तर्कों के JSON प्रतिनिधित्व के साथ एक प्रतिक्रिया बनाता है।

Json.dumps के साथ इस व्यवहार की नकल करने के लिए आपको कोड की कुछ अतिरिक्त पंक्तियों को जोड़ना होगा।

response = make_response(dumps(sample, cls=CustomEncoder))
response.headers['Content-Type'] = 'application/json'
response.headers['mimetype'] = 'application/json'
return response

आपको जेन्सिफाइज़ की प्रतिक्रिया को पूरी तरह से दोहराने के लिए एक तानाशाह को भी लौटना चाहिए। तो, पूरी फाइल इस तरह दिखाई देगी

from flask import make_response
from json import JSONEncoder, dumps


class CustomEncoder(JSONEncoder):
    def default(self, obj):
        if set(['quantize', 'year']).intersection(dir(obj)):
            return str(obj)
        elif hasattr(obj, 'next'):
            return list(obj)
        return JSONEncoder.default(self, obj)

@app.route('/get_reps/', methods=['GET'])
def get_reps():
    sample = ['some text', <datetime object>, 123]
    response = make_response(dumps({'result': sample}, cls=CustomEncoder))
    response.headers['Content-Type'] = 'application/json'
    response.headers['mimetype'] = 'application/json'
    return response

1
प्रश्न का फ्लास्क से कोई लेना-देना नहीं है।
ज़ोरान पावलोविक

2
सवाल अजगर के बारे में है। मेरा जवाब अजगर का उपयोग कर सवाल हल करता है। ओपी ने यह नहीं कहा कि क्या समाधान में कुछ पुस्तकालयों को शामिल करना या बाहर करना चाहिए। यह इस सवाल को पढ़ने वाले किसी अन्य व्यक्ति के लिए भी उपयोगी है, जो इसका विकल्प चाहता है pymongo
रबानो

वे सवाल करते हैं कि दोनों पायथन के बारे में हैं कि फ्लास्क के बारे में। प्रश्न के आपके उत्तर में फ्लास्क की भी आवश्यकता नहीं है, इसलिए मेरा सुझाव है कि आप इसे हटा दें।
ज़ोरान पावलोविच

3

इसे पार्स करने के लिए एक उदाहरण के साथ कोशिश करें:

#!/usr/bin/env python

import datetime
import json

import dateutil.parser  # pip install python-dateutil


class JSONEncoder(json.JSONEncoder):

    def default(self, obj):
        if isinstance(obj, datetime.datetime):
            return obj.isoformat()
        return super(JSONEncoder, self).default(obj)


def test():
    dts = [
        datetime.datetime.now(),
        datetime.datetime.now(datetime.timezone(-datetime.timedelta(hours=4))),
        datetime.datetime.utcnow(),
        datetime.datetime.now(datetime.timezone.utc),
    ]
    for dt in dts:
        dt_isoformat = json.loads(json.dumps(dt, cls=JSONEncoder))
        dt_parsed = dateutil.parser.parse(dt_isoformat)
        assert dt == dt_parsed
        print(f'{dt}, {dt_isoformat}, {dt_parsed}')
        # 2018-07-22 02:22:42.910637, 2018-07-22T02:22:42.910637, 2018-07-22 02:22:42.910637
        # 2018-07-22 02:22:42.910643-04:00, 2018-07-22T02:22:42.910643-04:00, 2018-07-22 02:22:42.910643-04:00
        # 2018-07-22 06:22:42.910645, 2018-07-22T06:22:42.910645, 2018-07-22 06:22:42.910645
        # 2018-07-22 06:22:42.910646+00:00, 2018-07-22T06:22:42.910646+00:00, 2018-07-22 06:22:42.910646+00:00


if __name__ == '__main__':
    test()

2

मेरा समाधान ...

from datetime import datetime
import json

from pytz import timezone
import pytz


def json_dt_serializer(obj):
    """JSON serializer, by macm.
    """
    rsp = dict()
    if isinstance(obj, datetime):
        rsp['day'] = obj.day
        rsp['hour'] = obj.hour
        rsp['microsecond'] = obj.microsecond
        rsp['minute'] = obj.minute
        rsp['month'] = obj.month
        rsp['second'] = obj.second
        rsp['year'] = obj.year
        rsp['tzinfo'] = str(obj.tzinfo)
        return rsp
    raise TypeError("Type not serializable")


def json_dt_deserialize(obj):
    """JSON deserialize from json_dt_serializer, by macm.
    """
    if isinstance(obj, str):
        obj = json.loads(obj)
    tzone = timezone(obj['tzinfo'])
    tmp_dt = datetime(obj['year'],
                      obj['month'],
                      obj['day'],
                      hour=obj['hour'],
                      minute=obj['minute'],
                      second=obj['second'],
                      microsecond=obj['microsecond'])
    loc_dt = tzone.localize(tmp_dt)
    deserialize = loc_dt.astimezone(tzone)
    return deserialize    

ठीक है, अब कुछ परीक्षण।

# Tests
now = datetime.now(pytz.utc)

# Using this solution
rsp = json_dt_serializer(now)
tmp = json_dt_deserialize(rsp)
assert tmp == now
assert isinstance(tmp, datetime) == True
assert isinstance(now, datetime) == True

# using default from json.dumps
tmp = json.dumps(datetime.now(pytz.utc), default=json_dt_serializer)
rsp = json_dt_deserialize(tmp)
assert isinstance(rsp, datetime) == True

# Lets try another timezone
eastern = timezone('US/Eastern')
now = datetime.now(eastern)
rsp = json_dt_serializer(now)
tmp = json_dt_deserialize(rsp)

print(tmp)
# 2015-10-22 09:18:33.169302-04:00

print(now)
# 2015-10-22 09:18:33.169302-04:00

# Wow, Works!
assert tmp == now

2

यहाँ JSON और वापस करने के लिए डेटाटाइम परिवर्तित करने के लिए मेरा पूरा समाधान है ..

import calendar, datetime, json

def outputJSON(obj):
    """Default JSON serializer."""

    if isinstance(obj, datetime.datetime):
        if obj.utcoffset() is not None:
            obj = obj - obj.utcoffset()

        return obj.strftime('%Y-%m-%d %H:%M:%S.%f')
    return str(obj)

def inputJSON(obj):
    newDic = {}

    for key in obj:
        try:
            if float(key) == int(float(key)):
                newKey = int(key)
            else:
                newKey = float(key)

            newDic[newKey] = obj[key]
            continue
        except ValueError:
            pass

        try:
            newDic[str(key)] = datetime.datetime.strptime(obj[key], '%Y-%m-%d %H:%M:%S.%f')
            continue
        except TypeError:
            pass

        newDic[str(key)] = obj[key]

    return newDic

x = {'Date': datetime.datetime.utcnow(), 34: 89.9, 12.3: 90, 45: 67, 'Extra': 6}

print x

with open('my_dict.json', 'w') as fp:
    json.dump(x, fp, default=outputJSON)

with open('my_dict.json') as f:
    my_dict = json.load(f, object_hook=inputJSON)

print my_dict

उत्पादन

{'Date': datetime.datetime(2013, 11, 8, 2, 30, 56, 479727), 34: 89.9, 45: 67, 12.3: 90, 'Extra': 6}
{'Date': datetime.datetime(2013, 11, 8, 2, 30, 56, 479727), 34: 89.9, 45: 67, 12.3: 90, 'Extra': 6}

JSON फ़ाइल

{"Date": "2013-11-08 02:30:56.479727", "34": 89.9, "45": 67, "12.3": 90, "Extra": 6}

इसने मुझे स्ट्रिंग्स, इनट्स, फ्लोट्स और डेटाइम वस्तुओं को आयात और निर्यात करने में सक्षम किया है। अन्य प्रकारों के लिए इसे बढ़ाना कठिन नहीं होना चाहिए।


1
यह पायथन 3 में विस्फोट करता है TypeError: 'str' does not support the buffer interface। यह 'wb'ओपन मोड के कारण है, होना चाहिए 'w'। यह डिसररलाइजेशन में भी उड़ा देता है जब हमारे पास डेट के समान डेटा होता है '0000891618-05-000338'लेकिन मिलान पैटर्न नहीं।
omikron


2

आम तौर पर डेटासेट को क्रमबद्ध करने के कई तरीके हैं, जैसे:

  1. आईएसओ स्ट्रिंग, छोटा और इसमें टाइमजोन जानकारी शामिल हो सकती है, जैसे @ jgbarah जवाब
  2. टाइमस्टैम्प (टाइमज़ोन डेटा खो गया है), उदाहरण के लिए @ JayTaylor's जवाब
  3. गुणों का शब्दकोश (समयक्षेत्र सहित)।

यदि आप आखिरी रास्ते से ठीक हैं, तो json_tricks पैकेज समय-समय सहित तिथियों, समय और डेटाटाइम को संभालता है।

from datetime import datetime
from json_tricks import dumps
foo = {'title': 'String', 'datetime': datetime(2012, 8, 8, 21, 46, 24, 862000)}
dumps(foo)

जो देता है:

{"title": "String", "datetime": {"__datetime__": null, "year": 2012, "month": 8, "day": 8, "hour": 21, "minute": 46, "second": 24, "microsecond": 862000}}

तो आपको बस इतना करना है

`pip install json_tricks`

और फिर के json_tricksबजाय से आयात करें json

इसे एक स्ट्रिंग, इंट या फ्लोट के रूप में संग्रहीत नहीं करने का लाभ डिकोडिंग के दौरान आता है: यदि आप सिर्फ एक स्ट्रिंग या विशेष रूप से इंट या फ्लोट से मुठभेड़ करते हैं, तो आपको यह जानने के लिए डेटा के बारे में कुछ जानना होगा कि क्या यह डेटाइम है। एक तानाशाह के रूप में, आप मेटाडेटा को स्टोर कर सकते हैं ताकि इसे स्वचालित रूप से डिकोड किया जा सके, जो कि हैjson_tricks आपके लिए है। यह मनुष्यों के लिए भी आसानी से संपादन योग्य है।

अस्वीकरण: यह मेरे द्वारा बनाया गया है। क्योंकि मुझे भी यही समस्या थी।


1

मुझे वर्गलैकमे के साथ वर्ग के अंदर क्रमबद्ध डेकोरेटर लिखते समय एक ही त्रुटि संदेश मिला। इसलिए इसके बजाय:

Class Puppy(Base):
    ...
    @property
    def serialize(self):
        return { 'id':self.id,
                 'date_birth':self.date_birth,
                  ...
                }

मैंने बस isoformat () का उपयोग करने के jgbarah के विचार को उधार लिया और isoformat () के साथ मूल मूल्य को जोड़ दिया, ताकि यह अब जैसा दिखता है:

                  ...
                 'date_birth':self.date_birth.isoformat(),
                  ...

1

यदि आप अपना स्वयं का स्वरूपण चाहते हैं तो एक त्वरित सुधार

for key,val in sample.items():
    if isinstance(val, datetime):
        sample[key] = '{:%Y-%m-%d %H:%M:%S}'.format(val) #you can add different formating here
json.dumps(sample)

1

यदि आप संचार के दोनों किनारों पर हैं तो आप jpr के साथ repr () और eval () फ़ंक्शन का उपयोग कर सकते हैं ।

import datetime, json

dt = datetime.datetime.now()
print("This is now: {}".format(dt))

dt1 = json.dumps(repr(dt))
print("This is serialised: {}".format(dt1))

dt2 = json.loads(dt1)
print("This is loaded back from json: {}".format(dt2))

dt3 = eval(dt2)
print("This is the same object as we started: {}".format(dt3))

print("Check if they are equal: {}".format(dt == dt3))

आप के रूप में डेटाटाइम आयात नहीं करना चाहिए

from datetime import datetime

क्योंकि eval शिकायत करेंगे। या आप eval को एक पैरामीटर के रूप में उत्तीर्ण कर सकते हैं। किसी भी मामले में यह काम करना चाहिए।


0

मुझे एक ही समस्या का सामना करना पड़ा जब django मॉडल ऑब्जेक्ट को JSON के रूप में डंप करने के लिए बाहरी करना। यहां बताया गया है कि आप इसे कैसे हल कर सकते हैं।

def externalize(model_obj):
  keys = model_obj._meta.get_all_field_names() 
  data = {}
  for key in keys:
    if key == 'date_time':
      date_time_obj = getattr(model_obj, key)
      data[key] = date_time_obj.strftime("%A %d. %B %Y")
    else:
      data[key] = getattr(model_obj, key)
  return data

0
def j_serial(o):     # self contained
    from datetime import datetime, date
    return str(o).split('.')[0] if isinstance(o, (datetime, date)) else None

उपरोक्त उपयोगिता का उपयोग:

import datetime
serial_d = j_serial(datetime.datetime.now())
if serial_d:
    print(serial_d)  # output: 2018-02-28 02:23:15

0

यह लाइब्रेरी सुपरजसन कर सकती है। और आप इस निर्देश https://superjson.readthedocs.io/index.html#extend का पालन ​​करके अपने स्वयं के पायथन ऑब्जेक्ट के लिए आसानी से json क्रमबद्ध कर सकते हैं

सामान्य अवधारणा है:

आपके कोड को अजगर के आधार पर सही क्रमांकन / deserialization विधि का पता लगाने की आवश्यकता है। आमतौर पर, पूर्ण वर्गनाम एक अच्छा पहचानकर्ता है।

और फिर आपकी सीर / डेसर विधि आपकी वस्तु को एक नियमित जोंस सीरियलैसेबल ऑब्जेक्ट में बदलने में सक्षम होना चाहिए, जेनेरिक पायथन प्रकार, तानाशाही, सूची, स्ट्रिंग, इंट, फ्लोट का संयोजन। और अपनी deser मेथड को उलट कर लागू करे।


-1

मैं 100% सही नहीं हो सकता, लेकिन यह क्रमबद्ध करने का सरल तरीका है

#!/usr/bin/python
import datetime,json

sampledict = {}
sampledict['a'] = "some string"
sampledict['b'] = datetime.datetime.now()

print sampledict   # output : {'a': 'some string', 'b': datetime.datetime(2017, 4, 15, 5, 15, 34, 652996)}

#print json.dumps(sampledict)

'''
output : 

Traceback (most recent call last):
  File "./jsonencodedecode.py", line 10, in <module>
    print json.dumps(sampledict)
  File "/usr/lib/python2.7/json/__init__.py", line 244, in dumps
    return _default_encoder.encode(obj)
  File "/usr/lib/python2.7/json/encoder.py", line 207, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python2.7/json/encoder.py", line 270, in iterencode
    return _iterencode(o, 0)
  File "/usr/lib/python2.7/json/encoder.py", line 184, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: datetime.datetime(2017, 4, 15, 5, 16, 17, 435706) is not JSON serializable


'''

sampledict['b'] = datetime.datetime.now().strftime("%B %d, %Y %H:%M %p")

afterdump = json.dumps(sampledict)

print afterdump  #output : {"a": "some string", "b": "April 15, 2017 05:18 AM"}

print type(afterdump) #<type 'str'>


afterloads = json.loads(afterdump) 

print afterloads # output : {u'a': u'some string', u'b': u'April 15, 2017 05:18 AM'}


print type(afterloads) # output :<type 'dict'> 
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.