আমি ব্যবহার পাইথন থেকে ধারাবাহিকভাবে আকারে একটি datetime.datetime বস্তুর পাঠাতে চান তাদেরকে JSON এবং JSON ব্যবহার জাভাস্ক্রিপ্ট মধ্যে ডি ধারাবাহিকভাবে। এই কাজ করতে সবচেয়ে ভালো উপায় কি?
আমি ব্যবহার পাইথন থেকে ধারাবাহিকভাবে আকারে একটি datetime.datetime বস্তুর পাঠাতে চান তাদেরকে JSON এবং JSON ব্যবহার জাভাস্ক্রিপ্ট মধ্যে ডি ধারাবাহিকভাবে। এই কাজ করতে সবচেয়ে ভালো উপায় কি?
উত্তর:
আপনি এটি পরিচালনা করতে json.dumps 'ডিফল্ট' পরামিতি যুক্ত করতে পারেন:
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"'
যা আইএসও 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)
ক্রস-ল্যাঙ্গুয়েজ প্রকল্পগুলির জন্য, আমি জানতে পেরেছি যে আরএফসি 3339 তারিখযুক্ত স্ট্রিংগুলি যাওয়ার সবচেয়ে ভাল উপায়। একটি আরএফসি 3339 তারিখটি দেখতে এমন দেখাচ্ছে:
1985-04-12T23:20:50.52Z
আমি মনে করি বেশিরভাগ ফর্ম্যাটটি সুস্পষ্ট। কিছুটা অস্বাভাবিক জিনিসটি শেষে "জেড" হতে পারে। এটি GMT / UTC এর জন্য দাঁড়িয়েছে। আপনি সিইএসটি (গ্রীষ্মে জার্মানি) এর জন্য অফসেট +02: 00 এর মতো টাইমজোনও যুক্ত করতে পারেন। আমি ব্যক্তিগতভাবে সবকিছু প্রদর্শিত না হওয়া পর্যন্ত ইউটিসি-তে রাখা পছন্দ করি।
প্রদর্শনের জন্য, তুলনা এবং সঞ্চয় করার জন্য আপনি এটিকে সমস্ত ভাষায় স্ট্রিং ফর্ম্যাটে রেখে যেতে পারেন। আপনার যদি গণনার জন্য তারিখের প্রয়োজন হয় তবে এটিকে বেশিরভাগ ভাষায় একটি নেটিভ ডেট অবজেক্টে রূপান্তর করা সহজ।
সুতরাং এটির মতো জেএসএন তৈরি করুন:
json.dump(datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ'))
দুর্ভাগ্যক্রমে, জাভাস্ক্রিপ্টের তারিখ নির্মাণকারী আরএফসি 3339 স্ট্রিং গ্রহণ করে না তবে ইন্টারনেটে অনেকগুলি পার্সার উপলব্ধ।
হুটুলস.হুজসন পাইথন কোডটিতে সাধারণত যে তারিখ / তারিখের সময়গুলি সঠিকভাবে টাইমজোনগুলি পরিচালনা করতে পারে সেগুলি সহ পাইথন কোডে আসতে পারে এমন হ্যান্ডলগুলি হ্যান্ডেল করার চেষ্টা করে।
datetime
: ডেটটাইম.আইসোফর্ম্যাট () এবং দ্বারা উভয় দ্বারা সমর্থিত simplejson
, যা ডিফল্টরূপে স্ট্রিং datetime
হিসাবে বস্তুগুলিকে ডাম্প করে দেবে isoformat
। ম্যানুয়াল strftime
হ্যাকিংয়ের দরকার নেই ।
datetime
বস্তুগুলি থেকে isoformat
স্ট্রিংয়ে স্বয়ংক্রিয় রূপান্তর পাচ্ছি না । আমার জন্য, simplejson.dumps(datetime.now())
ফলনTypeError: datetime.datetime(...) is not JSON serializable
json.dumps(datetime.datetime.now().isoformat())
যাদু যেখানে ঘটে।
আমি এটি কাজ করেছি।
ধরা যাক আপনার কাছে পাইথনের ডেটটাইম অবজেক্ট রয়েছে, d , ডেটটাইম.নু () দিয়ে তৈরি। এর মান হ'ল:
datetime.datetime(2011, 5, 25, 13, 34, 5, 787000)
আপনি এটি কোনও আইএসও 8601 ডেটটাইম স্ট্রিং হিসাবে জেএসএনে সিরিয়ালাইজ করতে পারেন:
import json
json.dumps(d.isoformat())
ডেটটাইম অবজেক্টের উদাহরণ হিসাবে সিরিয়ালযুক্ত হবে:
'"2011-05-25T13:34:05.787000"'
এই মানটি একবার জাভাস্ক্রিপ্ট স্তরে প্রাপ্ত হয়ে একটি তারিখ অবজেক্ট তৈরি করতে পারে:
var d = new Date("2011-05-25T13:34:05.787000");
জাভাস্ক্রিপ্ট ১.৮.৫ অনুসারে, তারিখের অবজেক্টগুলির একটি টোএসএন পদ্ধতি রয়েছে, যা একটি স্ট্যান্ডার্ড ফর্ম্যাটে স্ট্রিং দেয়। উপরের জাভাস্ক্রিপ্ট অবজেক্টটি জেএসএন-তে ফিরে সিরিয়ালাইজ করতে, সুতরাং আদেশটি হবে:
d.toJSON()
যা আপনাকে দেবে:
'2011-05-25T20:34:05.787Z'
পাইথনে একবার পাওয়া এই স্ট্রিংটিকে ডেটটাইম অবজেক্টে আবার ডিজিট্রাইজ করা যেতে পারে:
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 সাবক্লাস করতে পারেন এবং নিজস্ব কাস্টম সিরিয়ালাইজার সরবরাহ করতে ডিফল্ট () পদ্ধতিটি ওভাররাইড করতে পারেন:
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
মডিউলটি ব্যবহার করে ডেটটাইম.ডেটটাইম এবং ডেটটাইম.ডেট অবজেক্টগুলি পুনরাবৃত্তভাবে এনকোডিং এবং ডিকোড করার জন্য মোটামুটি সম্পূর্ণ সমাধান । %f
ডেটটাইম.ডেটটাইম.স্ট্রিপটাইম () ফর্ম্যাট স্ট্রিংটিতে ফর্ম্যাট কোডটি তখন থেকেই পাইথন> = 2.6 প্রয়োজন । পাইথন ২.৫ সমর্থনের জন্য, %f
আইএসও তারিখের স্ট্রিং থেকে মাইক্রোসেকেন্ডগুলি এটিকে রূপান্তরিত করার চেষ্টা করার আগে ড্রপ করে ফেলে দিন, তবে অবশ্যই আপনি মাইক্রোসেকেন্ডস যথাযথতা হ্রাস করবেন । অন্যান্য উত্স থেকে আইএসও তারিখের স্ট্রিংগুলির সাথে আন্তঃব্যবহারের জন্য, এতে টাইম জোনের নাম বা ইউটিসি অফসেট অন্তর্ভুক্ত থাকতে পারে, রূপান্তর হওয়ার আগে আপনাকে তারিখের স্ট্রিংয়ের কিছু অংশও ছাঁটাতে হবে। আইএসও তারিখের স্ট্রিংগুলির (ও অন্যান্য অনেক তারিখের ফর্ম্যাট) সম্পূর্ণ পার্সারের জন্য তৃতীয় পক্ষের ডেটুটিল মডিউলটি দেখুন।
জাভাস্ক্রিপ্ট আক্ষরিক অবজেক্ট স্বরলিপি বা কোনও বস্তুর মধ্যে নেস্টেড স্ট্রাকচারগুলিতে যখন 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 () জাভাস্ক্রিপ্টে উত্পাদন করে
আপনি যদি নিশ্চিত হন যে কেবল জাভাস্ক্রিপ্টই জেএসএন ব্যবহার করবে, তবে আমি Date
সরাসরি জাভাস্ক্রিপ্ট অবজেক্টগুলি পাস করতে পছন্দ করি ।
ctime()
উপর পদ্ধতি datetime
বস্তু একটি স্ট্রিং, যাতে জাভাস্ক্রিপ্ট তারিখ বস্তুর বুঝতে পারেন ফিরে আসবে।
import datetime
date = datetime.datetime.today()
json = '{"mydate":new Date("%s")}' % date.ctime()
জাভাস্ক্রিপ্ট আনন্দের সাথে একটি অবজেক্টকে আক্ষরিক হিসাবে ব্যবহার করবে এবং আপনি নিজের তারিখের অবজেক্টটি একেবারে অন্তর্নির্মিত পেয়েছেন।
.ctime()
সময় তথ্য পাস করার একটি খুব খারাপ উপায়, .isoformat()
অনেক ভাল। .ctime()
টাইমজোন এবং দিবালোক সংরক্ষণগুলি কীভাবে তা অস্তিত্ব নেই তা ফেলে দেয়। যে ফাংশন হত্যা করা উচিত।
গেমের দেরিতে ... :)
একটি খুব সাধারণ সমাধান হল জসন মডিউল ডিফল্ট প্যাচ করা। উদাহরণ স্বরূপ:
import json
import datetime
json.JSONEncoder.default = lambda self,obj: (obj.isoformat() if isinstance(obj, datetime.datetime) else None)
এখন, আপনি json.dumps () ব্যবহার করতে পারেন যেন এটি সর্বদা ডেটটাইম সমর্থন করে ...
json.dumps({'created':datetime.datetime.now()})
আপনি যদি জসন মডিউলটিতে সর্বদা লাথি মারার জন্য এবং আপনার বা অন্যরা জেএসন সিরিয়ালাইজেশন (বিদ্যমান কোডে বা না হয়) ব্যবহার করার উপায়টি পরিবর্তন না করতে চান তবে এই বোধগম্যতাটি উপলব্ধি করে।
মনে রাখবেন যে কেউ কেউ লাইব্রেরিগুলিকে প্যাচিংয়ের জন্য খারাপ অভ্যাস হিসাবে বিবেচনা করতে পারে as আপনি যদি একাধিক উপায়ে আপনার আবেদন বাড়িয়ে নিতে চান তবে বিশেষ যত্ন নেওয়া দরকার - এই জাতীয় ঘটনা, আমি রামেন বা জেটি দ্বারা সমাধানটি ব্যবহার করার এবং প্রতিটি ক্ষেত্রে যথাযথ জসন এক্সটেনশন বেছে নেওয়ার পরামর্শ দিই।
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'
যদি আপনি সেই জেডটি ছেড়ে দেন তবে কৌণিকের মতো সামনের ফ্রেমওয়ার্কগুলি ব্রাউজার-স্থানীয় টাইমজোনটিতে তারিখটি প্রদর্শন করতে পারে না:
> $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"
আমার পরামর্শ হল একটি লাইব্রেরি ব্যবহার করা। পাইপ.আর.ইগিতে বেশ কয়েকটি উপলব্ধ রয়েছে।
আমি এটি ব্যবহার করি, এটি ভাল কাজ করে: https://pypi.python.org/pypi/asjson
স্পষ্টতই "ডান" JSON (ভাল জাভাস্ক্রিপ্ট) তারিখের ফর্ম্যাটটি 2012-04-23T18: 25: 43.511Z - ইউটিসি এবং "জেড"। এটি ছাড়া জাভাস্ক্রিপ্ট স্ট্রিং থেকে তারিখ () অবজেক্ট তৈরি করার সময় ওয়েব ব্রাউজারের স্থানীয় সময় অঞ্চল ব্যবহার করবে will
"নিষ্পাপ" সময়ের জন্য (পাইথন কোনও সময় অঞ্চল ছাড়াই এমন সময়কে কল করে এবং এটি স্থানীয় বলে ধরে নেওয়া হয়) নীচে স্থানীয় সময় অঞ্চলকে বাধ্য করবে যাতে এটি তখন যথাযথভাবে ইউটিসিতে রূপান্তর করতে পারে:
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)
এটা এত কঠিন কেন.
পাইথন থেকে জাভাস্ক্রিপ্টের তারিখ রূপান্তরকরণের জন্য, তারিখের অবজেক্ট নির্দিষ্ট আইএসও ফর্ম্যাটে থাকা দরকার, যেমন আইএসও ফর্ম্যাট বা ইউনিক্স নম্বর। যদি আইএসও ফর্ম্যাটে কিছু তথ্য না থাকে তবে আপনি প্রথমে ডেট.পার্সের সাথে ইউনিক্স নম্বরে রূপান্তর করতে পারেন। তদ্ব্যতীত, ডেট.পারস পাশাপাশি প্রতিক্রিয়া নিয়ে কাজ করে যখন নতুন তারিখটি ব্যতিক্রম হতে পারে।
আপনার যদি মিলি সেকেন্ড ছাড়াই ডেটটাইম অবজেক্ট থাকে তবে নিম্নলিখিত বিষয়গুলি বিবেচনা করা দরকার। :
var unixDate = Date.parse('2016-01-08T19:00:00')
var desiredDate = new Date(unixDate).toLocaleDateString();
উদাহরণের তারিখটি সমানভাবে কোনও API কলের পরে ফলাফল.ডাটা অবজেক্টে পরিবর্তনশীল হতে পারে।
পছন্দসই বিন্যাসে তারিখটি প্রদর্শনের বিকল্পগুলির জন্য (যেমন দীর্ঘ সপ্তাহের দিনগুলি প্রদর্শন করতে) MDN ডকটি পরীক্ষা করে দেখুন ।