পাইথনের ধরণের মতো আমাকে আরএফসি 3339 স্ট্রিং পার্স করতে হবে ।"2008-09-03T20:56:35.450686Z"
datetime
আমি strptime
পাইথন স্ট্যান্ডার্ড লাইব্রেরিতে পেয়েছি , তবে এটি খুব সুবিধাজনক নয়।
এই কাজ করতে সবচেয়ে ভালো উপায় কি?
পাইথনের ধরণের মতো আমাকে আরএফসি 3339 স্ট্রিং পার্স করতে হবে ।"2008-09-03T20:56:35.450686Z"
datetime
আমি strptime
পাইথন স্ট্যান্ডার্ড লাইব্রেরিতে পেয়েছি , তবে এটি খুব সুবিধাজনক নয়।
এই কাজ করতে সবচেয়ে ভালো উপায় কি?
উত্তর:
পাইথন-ডেটুটিল প্যাকেজটি কেবল প্রশ্নের মতোই আরএফসি 3339 ডেটটাইম স্ট্রিংগুলি পার্স করতে পারে না, তবে অন্যান্য আইএসও 8601 তারিখ এবং সময় স্ট্রিং যা আরএফসি 3339 মেনে চলে না (যেমন কোনও ইউটিসি অফসেটবিহীন, বা প্রতিনিধিত্বকারীগুলি) শুধুমাত্র একটি তারিখ)।
>>> import dateutil.parser
>>> dateutil.parser.isoparse('2008-09-03T20:56:35.450686Z') # RFC 3339 format
datetime.datetime(2008, 9, 3, 20, 56, 35, 450686, tzinfo=tzutc())
>>> dateutil.parser.isoparse('2008-09-03T20:56:35.450686') # ISO 8601 extended format
datetime.datetime(2008, 9, 3, 20, 56, 35, 450686)
>>> dateutil.parser.isoparse('20080903T205635.450686') # ISO 8601 basic format
datetime.datetime(2008, 9, 3, 20, 56, 35, 450686)
>>> dateutil.parser.isoparse('20080903') # ISO 8601 basic format, date only
datetime.datetime(2008, 9, 3, 0, 0)
নোটটি dateutil.parser.isoparse
সম্ভবত আরও হ্যাকির চেয়ে কঠোর dateutil.parser.parse
, তবে তারা উভয়ই যথেষ্ট ক্ষমাশীল এবং আপনি যে স্ট্রিংটি প্রবেশ করেছেন তা ব্যাখ্যা করার চেষ্টা করবেন If আপনি যদি কোনও ভুল লেখার সম্ভাবনাটি মুছে ফেলতে চান তবে আপনাকে এইগুলির দুটির চেয়ে আরও কঠোর কিছু ব্যবহার করতে হবে ফাংশন।
পাইপির নামটি python-dateutil
নয়, dateutil
(ধন্যবাদ কোড3 মোনক 3 ই ):
pip install python-dateutil
আপনি পাইথন 3.7 ব্যবহার করেন, তাহলে কটাক্ষপাত আছে এই উত্তরটি সম্পর্কে datetime.datetime.fromisoformat
।
python-dateutil
না dateutil
, তাই: pip install python-dateutil
।
dateutil.parser
ইচ্ছাকৃতভাবে হ্যাকি: এটি ফর্ম্যাটটি অনুমান করার চেষ্টা করে এবং অস্পষ্ট ক্ষেত্রে অনিবার্য অনুমানগুলি (কেবলমাত্র হাতে কাস্টমাইজযোগ্য) করে। সুতরাং আপনার যদি অজানা ফর্ম্যাটটির ইনপুট পার্স করার প্রয়োজন হয় এবং মাঝে মাঝে ভুল প্রচার সহ্য করার পক্ষে ঠিক থাকে তবে এটি ব্যবহার করুন।
datetime
মান গ্রন্থাগার ইনভার্টারিং জন্য একটি ফাংশন চালু datetime.isoformat()
।
classmethod
datetime.fromisoformat(date_string)
:একটি ফিরতি
datetime
একটি সংশ্লিষ্টdate_string
ফরম্যাটের দ্বারা নির্গত একdate.isoformat()
এবংdatetime.isoformat()
।বিশেষত, এই ফাংশনটি (গুলি) বিন্যাসে স্ট্রিং সমর্থন করে:
YYYY-MM-DD[*HH[:MM[:SS[.mmm[mmm]]]][+HH:MM[:SS[.ffffff]]]]
যেখানে
*
কোনও একক চরিত্রের সাথে মেলে।সাবধানতা : এটি নির্বিচারে আইএসও 8601 স্ট্রিংকে পার্সিং সমর্থন করে না - এটি কেবলমাত্র এর বিপরীতমুখী ক্রিয়াকলাপ হিসাবে চিহ্নিত
datetime.isoformat()
।
ব্যবহারের উদাহরণ:
from datetime import datetime
date = datetime.fromisoformat('2017-01-01T12:30:59.000000')
datetime
থাকতে পারে tzinfo
এবং এভাবে টাইমজোন আউটপুট পাওয়া যায় তবে datetime.fromisoformat()
tzinfo কে পার্স করে না? বাগের মতো মনে হচ্ছে ..
isoformat
। এটি "2008-09-03T20:56:35.450686Z"
পিছনে থাকার কারণে প্রশ্নে উদাহরণটি গ্রহণ করে না Z
তবে তা গ্রহণ করে "2008-09-03T20:56:35.450686"
।
Z
জন্য ইনপুট স্ক্রিপ্টটি সংশোধন করা যেতে পারে date_string.replace("Z", "+00:00")
।
পাইথন ২.6+ এবং পাই 3 কে-তে নোট করুন,% f অক্ষর মাইক্রোসেকেন্ডগুলি ধরে।
>>> datetime.datetime.strptime("2008-09-03T20:56:35.450686Z", "%Y-%m-%dT%H:%M:%S.%fZ")
এখানে সমস্যা দেখুন
strptime
কে পার্স করা বাস্তবে অসম্ভব।
datetime.datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%S.%f')
সুতরাং এটি কৌশলটি করেছে
বেশ কয়েকটি উত্তর এখানে আরএফসি 3339 বা আইএসও 8601 তারিখের সময়কে জোনের সাথে পার্স করতে ব্যবহার করার পরামর্শ দেয়datetime.datetime.strptime
যেমন প্রশ্নের মধ্যে প্রদর্শিত হয়েছে:
2008-09-03T20:56:35.450686Z
এটি একটি খারাপ ধারণা।
ধরে নিই যে আপনি শূন্য ব্যতীত ইউটিসি অফসেটের সমর্থন সহ পুরো আরএফসি 3339 ফর্ম্যাটটিকে সমর্থন করতে চান, তবে এই উত্তরগুলির কোডটি কার্যকর করে না। আসলে এটি কাজ করতে পারে না , কারণ আরএফসি 3339 সিনট্যাক্স ব্যবহার করে পার্স strptime
করা অসম্ভব। পাইথনের ডেটটাইম মডিউল দ্বারা ব্যবহৃত ফর্ম্যাট স্ট্রিংগুলি আরএফসি 3339 সিনট্যাক্স বর্ণনা করতে অক্ষম।
সমস্যাটি ইউটিসি অফসেট। জন্য RFC 3339 ইন্টারনেটের তারিখ / সময় ফর্ম্যাট প্রত্যেক তারিখ-সময় একটি UTC অফসেট অন্তর্ভুক্ত, এবং ঐ অফসেট পারেন হতে পারে প্রয়োজন Z
(ছোট "জুলু সময়" এর জন্য) অথবা মধ্যে +HH:MM
বা -HH:MM
ফরম্যাট, মত +05:00
বা -10:30
।
ফলস্বরূপ, এগুলি সমস্ত বৈধ আরএফসি 3339 তারিখের সময়:
2008-09-03T20:56:35.450686Z
2008-09-03T20:56:35.450686+05:00
2008-09-03T20:56:35.450686-10:30
হায়রে, বিন্যাস স্ট্রিং দ্বারা ব্যবহৃত strptime
এবং strftime
কোন নির্দেশ আছে বোঝায় যা RFC 3339 বিন্যাসে ইউটিসি অফসেট অনুরূপ। তারা যে নির্দেশনাগুলি সমর্থন করে তার একটি সম্পূর্ণ তালিকা https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavier এ পাওয়া যাবে এবং তালিকার অন্তর্ভুক্ত একমাত্র ইউটিসি অফসেট নির্দেশিকা হ'ল %z
:
% z- র
ইউটিসি + এইচএইচএমএম বা-এইচএমএমএম আকারে অফসেট (বস্তুটি নিখরচায় হলে খালি স্ট্রিং)।
উদাহরণ: (খালি), +0000, -0400, +1030
এটি একটি আরএফসি 3339 অফসেটের ফর্ম্যাটটির সাথে মেলে না এবং সত্যই যদি আমরা %z
ফর্ম্যাট স্ট্রিংটিতে ব্যবহার করার চেষ্টা করি এবং একটি আরএফসি 3339 তারিখ বিশ্লেষণ করি, আমরা ব্যর্থ হব:
>>> from datetime import datetime
>>> datetime.strptime("2008-09-03T20:56:35.450686Z", "%Y-%m-%dT%H:%M:%S.%f%z")
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python3.4/_strptime.py", line 500, in _strptime_datetime
tt, fraction = _strptime(data_string, format)
File "/usr/lib/python3.4/_strptime.py", line 337, in _strptime
(data_string, format))
ValueError: time data '2008-09-03T20:56:35.450686Z' does not match format '%Y-%m-%dT%H:%M:%S.%f%z'
>>> datetime.strptime("2008-09-03T20:56:35.450686+05:00", "%Y-%m-%dT%H:%M:%S.%f%z")
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python3.4/_strptime.py", line 500, in _strptime_datetime
tt, fraction = _strptime(data_string, format)
File "/usr/lib/python3.4/_strptime.py", line 337, in _strptime
(data_string, format))
ValueError: time data '2008-09-03T20:56:35.450686+05:00' does not match format '%Y-%m-%dT%H:%M:%S.%f%z'
(প্রকৃতপক্ষে, উপরেরটি পাইথন 3 তে আপনি যা দেখবেন Py পাইথন 2 এ আমরা আরও সাধারণ কারণে ব্যর্থ হব, যা পাইথন 2 এ নির্দেশনাটি strptime
মোটেও প্রয়োগ করে না%z
))
এখানে একাধিক উত্তর যা তাদের strptime
চারিত্রিক Z
বিন্যাসে আক্ষরিক অন্তর্ভুক্ত করে এটিকে ঘিরে কাজ করার সুপারিশ করে যা Z
প্রশ্নকর্তার উদাহরণ ডেটটাইম স্ট্রিংয়ের সাথে মেলে (এবং এটি বাতিল করে দেয়, সময়সীমা datetime
ছাড়াই কোনও অবজেক্ট তৈরি করে ):
>>> datetime.strptime("2008-09-03T20:56:35.450686Z", "%Y-%m-%dT%H:%M:%S.%fZ")
datetime.datetime(2008, 9, 3, 20, 56, 35, 450686)
যেহেতু এটি টাইমজোন তথ্যকে মূল ডেটটাইম স্ট্রিংয়ের অন্তর্ভুক্ত করে, তাই আমাদের এমনকি এই ফলাফলটিকে সঠিক হিসাবে বিবেচনা করা উচিত কিনা তা প্রশ্নবিদ্ধ। তবে আরও গুরুত্বপূর্ণ, যেহেতু এই পদ্ধতির কোনও নির্দিষ্ট ইউটিসি অফসেটটিকে হার্ড কোডিংয়ের সাথে ফর্ম্যাট স্ট্রিংয়ের সাথে জড়িত রয়েছে , তাই এটি কোনও ইউটিসি অফসেটের সাথে কোনও আরএফসি 3339 ডেটটাইমকে পার্স করার চেষ্টা করার মুহুর্তটিকে শ্বাসরোধ করবে:
>>> datetime.strptime("2008-09-03T20:56:35.450686+05:00", "%Y-%m-%dT%H:%M:%S.%fZ")
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python3.4/_strptime.py", line 500, in _strptime_datetime
tt, fraction = _strptime(data_string, format)
File "/usr/lib/python3.4/_strptime.py", line 337, in _strptime
(data_string, format))
ValueError: time data '2008-09-03T20:56:35.450686+05:00' does not match format '%Y-%m-%dT%H:%M:%S.%fZ'
আপনি যদি নিশ্চিত না হন তবে আপনাকে জুলু সময়ে কেবল আরএফসি 3339 ডেটটাইম সমর্থন করতে হবে এবং অন্যান্য টাইমজোন অফসেটযুক্ত নয়, ব্যবহার করবেন না strptime
। পরিবর্তে এখানে বর্ণিত বর্ণিত আরও অনেক পদ্ধতির একটি ব্যবহার করুন।
strptime()
পাইথন ৩.7-এ এখন এই উত্তরে অসম্ভব হিসাবে বর্ণিত সমস্ত কিছুই সমর্থন করে (টাইমজোন অফসেটে 'জেড' আক্ষরিক এবং ':')। দুর্ভাগ্যক্রমে, আর একটি কর্নারের কেস রয়েছে যা আরএফসি 3339 মৌলিকভাবে আইএসও 8601 এর সাথে অসামঞ্জস্যপূর্ণ করে তোলে, যথা, প্রাক্তনটি একটি নেতিবাচক নাল টাইমজোনকে অফসেট -00: 00 এবং পরে দেয় না।
Iso8601 মডিউল চেষ্টা করুন ; এটা ঠিক এটা করে।
পাইথন.আর উইকিতে ওয়ার্কিং উইথটাইম পৃষ্ঠায় আরও কয়েকটি বিকল্প উল্লেখ করা হয়েছে ।
iso8601.parse_date("2008-09-03T20:56:35.450686Z")
আমদানি পুনরায়, তারিখের সময় গুলি = "2008-09-03T20: 56: 35.450686Z" d = ডেটটাইম.ডেটটাইম (* মানচিত্র (int, re.split ('[^ \ d]', গুলি) [: - 1]))
datetime.datetime(*map(int, re.findall('\d+', s))
আপনি কি সঠিক ত্রুটি পেয়েছেন? এটি কি নীচের মতো?
>>> datetime.datetime.strptime("2008-08-12T12:20:30.656234Z", "%Y-%m-%dT%H:%M:%S.Z")
ValueError: time data did not match format: data=2008-08-12T12:20:30.656234Z fmt=%Y-%m-%dT%H:%M:%S.Z
যদি হ্যাঁ, আপনি "" "তে আপনার ইনপুট স্ট্রিংটি বিভক্ত করতে পারেন এবং তারপরে যে তারিখটি পেয়েছেন তার সাথে মাইক্রোসেকেন্ডগুলি যুক্ত করতে পারেন।
এটা চেষ্টা কর:
>>> def gt(dt_str):
dt, _, us= dt_str.partition(".")
dt= datetime.datetime.strptime(dt, "%Y-%m-%dT%H:%M:%S")
us= int(us.rstrip("Z"), 10)
return dt + datetime.timedelta(microseconds=us)
>>> gt("2008-08-12T12:20:30.656234Z")
datetime.datetime(2008, 8, 12, 12, 20, 30, 656234)
""
বা "Z"
, তাহলে এটি ঘন্টা / মিনিট, যা সরাসরি থেকে / DATETIME বস্তু থেকে বিয়োগ যোগ করা যেতে পারে একটি অফসেট হতে হবে। আপনি এটি পরিচালনা করতে একটি tzinfo সাবক্লাস তৈরি করতে পারেন, তবে সম্ভবত এটি পুনরুদ্ধার করা হয়নি।
পাইথন ৩.7 থেকে শুরু করে, স্ট্রিমটাইম ইউটিসি অফসেটে ( উত্স ) কোলন ডিলিমিটারগুলিকে সমর্থন করে । সুতরাং আপনি তারপর ব্যবহার করতে পারেন:
import datetime
datetime.datetime.strptime('2018-01-31T09:24:31.488670+00:00', '%Y-%m-%dT%H:%M:%S.%f%z')
সম্পাদনা করুন:
মার্টিজন দ্বারা চিহ্নিত হিসাবে, আপনি যদি আইসফর্ম্যাট () ব্যবহার করে ডেটটাইম অবজেক্ট তৈরি করেন তবে আপনি কেবল ডেটটাইম.ফর্মিসফর্ম্যাট () ব্যবহার করতে পারেন
datetime.fromisoformat()
যা হ্যান্ডলগুলি স্বয়ংক্রিয়ভাবে আপনার ইনপুট মত স্ট্রিং: datetime.datetime.isoformat('2018-01-31T09:24:31.488670+00:00')
।
datetime.fromisoformat()
এবংdatetime.isoformat()
এই দিনগুলিতে তীরটি তৃতীয় পক্ষের সমাধান হিসাবেও ব্যবহার করা যেতে পারে:
>>> import arrow
>>> date = arrow.get("2008-09-03T20:56:35.450686Z")
>>> date.datetime
datetime.datetime(2008, 9, 3, 20, 56, 35, 450686, tzinfo=tzutc())
কেবলমাত্র python-dateutil
মডিউলটি ব্যবহার করুন :
>>> import dateutil.parser as dp
>>> t = '1984-06-02T19:05:00.000Z'
>>> parsed_t = dp.parse(t)
>>> print(parsed_t)
datetime.datetime(1984, 6, 2, 19, 5, tzinfo=tzutc())
455051100
( epochconverter.com এ চেক করা হয়েছে ) ,,, যদি না আমি কিছু মিস করছি?
আপনি যদি ডেটুটিল ব্যবহার করতে না চান তবে আপনি এই ফাংশনটি ব্যবহার করে দেখতে পারেন:
def from_utc(utcTime,fmt="%Y-%m-%dT%H:%M:%S.%fZ"):
"""
Convert UTC time string to time.struct_time
"""
# change datetime.datetime to time, return time.struct_time type
return datetime.datetime.strptime(utcTime, fmt)
টেস্ট:
from_utc("2007-03-04T21:08:12.123Z")
ফলাফল:
datetime.datetime(2007, 3, 4, 21, 8, 12, 123000)
strptime
। এটি একটি খারাপ ধারণা কারণ এটি কোনও ইউটিসি অফসেটের সাথে কোনও ডেটটাইমকে বিশ্লেষণ করতে ব্যর্থ হবে এবং ব্যতিক্রম বাড়াবে। আমার উত্তর দেখুন যা বর্ণনা করে যে কীভাবে আরআরএফসি 3339 কে স্ট্রপটাইমের সাথে পার্স করা আসলে অসম্ভব।
toISOString
পদ্ধতিতে আপনার তারিখের স্ট্রিং তৈরি হয়েছিল । তবে এই উত্তরে জুলু সময়ের তারিখের সীমাবদ্ধতার কোনও উল্লেখ নেই, বা প্রশ্নটি ইঙ্গিত দেয়নি যে এটি যা প্রয়োজন, এবং কেবল এটি ব্যবহার করে dateutil
যা পার্স করতে পারে তা প্রায় সমান সুবিধাজনক এবং কম সংকীর্ণ।
আপনি যদি জ্যাঙ্গোর সাথে কাজ করছেন, এটি তারিখ পার্সী মডিউল সরবরাহ করে যা সময় অঞ্চল সহ আইএসও বিন্যাসের অনুরূপ ফর্ম্যাটগুলির একটি গোছা গ্রহণ করে।
আপনি যদি জ্যাঙ্গো ব্যবহার করছেন না এবং আপনি এখানে উল্লিখিত অন্য একটি গ্রন্থাগার ব্যবহার করতে না চান, আপনি সম্ভবত আপনার প্রকল্পে ডেটপার্সের জন্য জ্যাঙ্গো উত্স কোডটি মানিয়ে নিতে পারেন।
DateTimeField
আপনি যখন স্ট্রিংয়ের মান সেট করেন তখন জাজানো এর ব্যবহার করে।
আমি আইএসও 8601 টাইমস্ট্যাম্পগুলি পার্স করার দ্রুততম উপায় হিসাবে সিসো 8601 পেয়েছি । নামটি যেমন বোঝায়, এটি সিতে প্রয়োগ করা হয়েছে
import ciso8601
ciso8601.parse_datetime('2014-01-09T21:48:00.921000+05:30')
GitHub রেপো README অন্যান্য উত্তর তালিকাবদ্ধ অন্যান্য লাইব্রেরি সব বনাম তাদের> 10x speedup দেখায়।
আমার ব্যক্তিগত প্রকল্পে প্রচুর আইএসও 8601 পার্সিং জড়িত। কেবল কলটি স্যুইচ করতে এবং 10x দ্রুত গতিতে সক্ষম হতে পেরে ভাল লাগছিল। :)
সম্পাদনা করুন: আমি তখন থেকে সিসো 8601 এর একজন রক্ষণাবেক্ষণকারী হয়েছি। এখন আগের চেয়ে দ্রুত!
datetime.strptime()
পরবর্তী তাত্পর্যপূর্ণ সমাধানটি দেখানোর জন্য অন্তর্দৃষ্টিপূর্ণ ছিল । সমস্ত তথ্য একসাথে রাখার জন্য ধন্যবাদ!
datetime.strptime()
কোনও সম্পূর্ণ আইএসও 8601 পার্সিং লাইব্রেরি নয়। আপনি পাইথন ৩.7 এ থাকলে আপনি সেই datetime.fromisoformat()
পদ্ধতিটি ব্যবহার করতে পারেন যা কিছুটা নমনীয়। আপনি পার্সারগুলির এই আরও সম্পূর্ণ তালিকায় আগ্রহী হতে পারেন যা শীঘ্রই সিসো 8601 পুনরায় পড়াতে মার্জ করা উচিত।
এটি পাইথন ৩.২ এর পরে স্টাডলিবের জন্য কাজ করে (ধরে নিলে সমস্ত টাইমস্ট্যাম্পগুলি ইউটিসি):
from datetime import datetime, timezone, timedelta
datetime.strptime(timestamp, "%Y-%m-%dT%H:%M:%S.%fZ").replace(
tzinfo=timezone(timedelta(0)))
উদাহরণ স্বরূপ,
>>> datetime.utcnow().replace(tzinfo=timezone(timedelta(0)))
... datetime.datetime(2015, 3, 11, 6, 2, 47, 879129, tzinfo=datetime.timezone.utc)
strptime
। এটি একটি খারাপ ধারণা কারণ এটি কোনও ইউটিসি অফসেটের সাথে কোনও ডেটটাইমকে বিশ্লেষণ করতে ব্যর্থ হবে এবং ব্যতিক্রম বাড়াবে। আমার উত্তর দেখুন যা বর্ণনা করে যে কীভাবে আরআরএফসি 3339 কে স্ট্রপটাইমের সাথে পার্স করা আসলে অসম্ভব।
timezone.utc
পরিবর্তে ব্যবহার করতে পারে timezone(timedelta(0))
। এছাড়াও, কোডটি পাইথন ২.6++ (কমপক্ষে) তে কাজ করে যদি আপনি tzinfo অবজেক্ট সরবরাহ utc
করেন
%Z
পাইথনের অতি সাম্প্রতিক সংস্করণগুলিতে টাইমজোন ব্যবহার করতে পারেন ।
datetime.datetime
তৃতীয় পক্ষের মডিউলগুলি ইনস্টল না করে কোনও আইএসও 8601 -র মতো তারিখের স্ট্রিংটিকে একটি ইউনিক্স টাইমস্ট্যাম্পে বা সমস্ত সমর্থিত পাইথন সংস্করণে অবজেক্ট করার জন্য সোজা উপায় S এসকিউএলাইটের তারিখ পার্সার ব্যবহার করা ।
#!/usr/bin/env python
from __future__ import with_statement, division, print_function
import sqlite3
import datetime
testtimes = [
"2016-08-25T16:01:26.123456Z",
"2016-08-25T16:01:29",
]
db = sqlite3.connect(":memory:")
c = db.cursor()
for timestring in testtimes:
c.execute("SELECT strftime('%s', ?)", (timestring,))
converted = c.fetchone()[0]
print("%s is %s after epoch" % (timestring, converted))
dt = datetime.datetime.fromtimestamp(int(converted))
print("datetime is %s" % dt)
আউটপুট:
2016-08-25T16:01:26.123456Z is 1472140886 after epoch
datetime is 2016-08-25 12:01:26
2016-08-25T16:01:29 is 1472140889 after epoch
datetime is 2016-08-25 12:01:29
আমি আইএসও 8601 স্ট্যান্ডার্ডের জন্য একটি পার্সার কোড করেছি এবং এটি গিটহাব: https://github.com/boxed/iso8601 এ রেখেছি । এই বাস্তবায়নটি পাইথনের ডেটটাইম মডিউলটির সমর্থিত তারিখের সীমা ছাড়ার মেয়াদ, বিরতি, পর্যায়ক্রমের বিরতি এবং তারিখ ব্যতীত স্পেসিফিকেশনের সমস্ত কিছুই সমর্থন করে।
টেস্ট অন্তর্ভুক্ত! : P: P
জ্যাঙ্গোর পার্স_ডেটটাইম () ফাংশন ইউটিসি অফসেটের সাথে তারিখগুলি সমর্থন করে:
parse_datetime('2016-08-09T15:12:03.65478Z') =
datetime.datetime(2016, 8, 9, 15, 12, 3, 654780, tzinfo=<UTC>)
সুতরাং এটি পুরো প্রকল্পের মধ্যে ক্ষেত্রগুলিতে আইএসও 8601 তারিখ পার্স করার জন্য ব্যবহার করা যেতে পারে:
from django.utils import formats
from django.forms.fields import DateTimeField
from django.utils.dateparse import parse_datetime
class DateTimeFieldFixed(DateTimeField):
def strptime(self, value, format):
if format == 'iso-8601':
return parse_datetime(value)
return super().strptime(value, format)
DateTimeField.strptime = DateTimeFieldFixed.strptime
formats.ISO_INPUT_FORMATS['DATETIME_INPUT_FORMATS'].insert(0, 'iso-8601')
কারণ আইএসও 8601 মূলত, colচ্ছিক কলোন এবং ড্যাশগুলির উপস্থিতিগুলিকে অনেকগুলি উপস্থিত করার অনুমতি দেয় CCYY-MM-DDThh:mm:ss[Z|(+|-)hh:mm]
। আপনি যদি স্ট্রপটাইম ব্যবহার করতে চান তবে আপনাকে প্রথমে সেই বৈকল্পিকতাগুলি সরিয়ে ফেলতে হবে।
লক্ষ্যটি হ'ল একটি ইউটিসি ডেটটাইম অবজেক্ট তৈরি করা।
2016-06-29T19:36:29.3453Z
:
datetime.datetime.strptime(timestamp.translate(None, ':-'), "%Y%m%dT%H%M%S.%fZ")
2016-06-29T19:36:29.3453-0400
বা 2008-09-03T20:56:35.450686+05:00
নিম্নলিখিত ব্যবহার করুন। এগুলি পার্সে 20080903T205635.450686+0500
আরও ধারাবাহিক / সহজ করার মতো পরিবর্তনশীল ডিলিমিটার ছাড়াই সমস্ত প্রকরণকে কোনও কিছুতে রূপান্তরিত করে ।
import re
# this regex removes all colons and all
# dashes EXCEPT for the dash indicating + or - utc offset for the timezone
conformed_timestamp = re.sub(r"[:]|([-](?!((\d{2}[:]\d{2})|(\d{4}))$))", '', timestamp)
datetime.datetime.strptime(conformed_timestamp, "%Y%m%dT%H%M%S.%f%z" )
%z
স্ট্র্যাপটাইম নির্দেশকে সমর্থন করে না (আপনি এর মতো কিছু দেখতে পান ValueError: 'z' is a bad directive in format '%Y%m%dT%H%M%S.%f%z'
) তবে আপনাকে Z
(ইউটিসি) থেকে ম্যানুয়ালি সময়টি অফসেট করতে হবে । নোটটি %z
অজগর সংস্করণ <3 এ আপনার সিস্টেমে কাজ করতে পারে না কারণ এটি সি লাইব্রেরির সহায়তার উপর নির্ভর করে যা সিস্টেম / পাইথন বিল্ড টাইপ (যেমন জাইথন, সিথন ইত্যাদি) জুড়ে পরিবর্তিত হয়।
import re
import datetime
# this regex removes all colons and all
# dashes EXCEPT for the dash indicating + or - utc offset for the timezone
conformed_timestamp = re.sub(r"[:]|([-](?!((\d{2}[:]\d{2})|(\d{4}))$))", '', timestamp)
# split on the offset to remove it. use a capture group to keep the delimiter
split_timestamp = re.split(r"[+|-]",conformed_timestamp)
main_timestamp = split_timestamp[0]
if len(split_timestamp) == 3:
sign = split_timestamp[1]
offset = split_timestamp[2]
else:
sign = None
offset = None
# generate the datetime object without the offset at UTC time
output_datetime = datetime.datetime.strptime(main_timestamp +"Z", "%Y%m%dT%H%M%S.%fZ" )
if offset:
# create timedelta based on offset
offset_delta = datetime.timedelta(hours=int(sign+offset[:-2]), minutes=int(sign+offset[-2:]))
# offset datetime with timedelta
output_datetime = output_datetime + offset_delta
২. এক্স স্ট্যান্ডার্ড লাইব্রেরির সাথে কাজ করে এমন কিছুর জন্য চেষ্টা করুন:
calendar.timegm(time.strptime(date.split(".")[0]+"UTC", "%Y-%m-%dT%H:%M:%S%Z"))
ক্যালেন্ডার.টাইমগেমটি সময়.এমকেটাইমের অনুপস্থিত জিএম সংস্করণ।
অজানা তারিখের স্ট্রিংকে বিশ্লেষণ করলে পাইথন-ডেটুটিয়েল একটি ব্যতিক্রম ছুঁড়ে ফেলবে, তাই আপনি ব্যতিক্রমটি ধরতে চাইতে পারেন।
from dateutil import parser
ds = '2012-60-31'
try:
dt = parser.parse(ds)
except ValueError, e:
print '"%s" is an invalid date' % ds
আজকাল মায়া রয়েছে: জনপ্রিয় অনুরোধগুলির লেখক : মানুষের জন্য তারিখের সময় : মানুষের জন্য এইচটিটিপি ™ প্যাকেজ:
>>> import maya
>>> str = '2008-09-03T20:56:35.450686Z'
>>> maya.MayaDT.from_rfc3339(str).datetime()
datetime.datetime(2008, 9, 3, 20, 56, 35, 450686, tzinfo=<UTC>)
অন্য একটি উপায় হল ISO-8601 এর জন্য বিশেষ পার্সার ব্যবহার করা ডেটুটিল পার্সারের আইসোপার্স ফাংশনটি ব্যবহার করা :
from dateutil import parser
date = parser.isoparse("2008-09-03T20:56:35.450686+01:00")
print(date)
আউটপুট:
2008-09-03 20:56:35.450686+01:00
এই ফাংশনটি স্ট্যান্ডার্ড পাইথন ফাংশন ডেটটাইমের জন্য ডকুমেন্টেশনেও উল্লেখ করা হয়েছে romফ্রেমিসোফর্ম্যাট :
তৃতীয় পক্ষের প্যাকেজ ডেটুটিলে আরও একটি পূর্ণ বৈশিষ্ট্যযুক্ত আইএসও 8601 পার্সার, ডেটুটি.এল পার্সার.আইসোপার্স উপলব্ধ।
ডেটটাইমের সমস্ত সম্ভাব্য আইএসও ফর্ম্যাটগুলির জন্য অ্যাকাউন্টে আমদানি করার জন্য দুর্দান্ত মার্ক আমেরির উত্তরের জন্য ধন্যবাদ :
class FixedOffset(tzinfo):
"""Fixed offset in minutes: `time = utc_time + utc_offset`."""
def __init__(self, offset):
self.__offset = timedelta(minutes=offset)
hours, minutes = divmod(offset, 60)
#NOTE: the last part is to remind about deprecated POSIX GMT+h timezones
# that have the opposite sign in the name;
# the corresponding numeric value is not used e.g., no minutes
self.__name = '<%+03d%02d>%+d' % (hours, minutes, -hours)
def utcoffset(self, dt=None):
return self.__offset
def tzname(self, dt=None):
return self.__name
def dst(self, dt=None):
return timedelta(0)
def __repr__(self):
return 'FixedOffset(%d)' % (self.utcoffset().total_seconds() / 60)
def __getinitargs__(self):
return (self.__offset.total_seconds()/60,)
def parse_isoformat_datetime(isodatetime):
try:
return datetime.strptime(isodatetime, '%Y-%m-%dT%H:%M:%S.%f')
except ValueError:
pass
try:
return datetime.strptime(isodatetime, '%Y-%m-%dT%H:%M:%S')
except ValueError:
pass
pat = r'(.*?[+-]\d{2}):(\d{2})'
temp = re.sub(pat, r'\1\2', isodatetime)
naive_date_str = temp[:-5]
offset_str = temp[-5:]
naive_dt = datetime.strptime(naive_date_str, '%Y-%m-%dT%H:%M:%S.%f')
offset = int(offset_str[-4:-2])*60 + int(offset_str[-2:])
if offset_str[0] == "-":
offset = -offset
return naive_dt.replace(tzinfo=FixedOffset(offset))
def parseISO8601DateTime(datetimeStr):
import time
from datetime import datetime, timedelta
def log_date_string(when):
gmt = time.gmtime(when)
if time.daylight and gmt[8]:
tz = time.altzone
else:
tz = time.timezone
if tz > 0:
neg = 1
else:
neg = 0
tz = -tz
h, rem = divmod(tz, 3600)
m, rem = divmod(rem, 60)
if neg:
offset = '-%02d%02d' % (h, m)
else:
offset = '+%02d%02d' % (h, m)
return time.strftime('%d/%b/%Y:%H:%M:%S ', gmt) + offset
dt = datetime.strptime(datetimeStr, '%Y-%m-%dT%H:%M:%S.%fZ')
timestamp = dt.timestamp()
return dt + timedelta(hours=dt.hour-time.gmtime(timestamp).tm_hour)
নোট করুন যে স্ট্রিংটি শেষ না হলে আমাদের দেখতে হবে Z
, আমরা ব্যবহার করে পার্স করতে পারি %z
।
প্রাথমিকভাবে আমি চেষ্টা করেছি:
from operator import neg, pos
from time import strptime, mktime
from datetime import datetime, tzinfo, timedelta
class MyUTCOffsetTimezone(tzinfo):
@staticmethod
def with_offset(offset_no_signal, signal): # type: (str, str) -> MyUTCOffsetTimezone
return MyUTCOffsetTimezone((pos if signal == '+' else neg)(
(datetime.strptime(offset_no_signal, '%H:%M') - datetime(1900, 1, 1))
.total_seconds()))
def __init__(self, offset, name=None):
self.offset = timedelta(seconds=offset)
self.name = name or self.__class__.__name__
def utcoffset(self, dt):
return self.offset
def tzname(self, dt):
return self.name
def dst(self, dt):
return timedelta(0)
def to_datetime_tz(dt): # type: (str) -> datetime
fmt = '%Y-%m-%dT%H:%M:%S.%f'
if dt[-6] in frozenset(('+', '-')):
dt, sign, offset = strptime(dt[:-6], fmt), dt[-6], dt[-5:]
return datetime.fromtimestamp(mktime(dt),
tz=MyUTCOffsetTimezone.with_offset(offset, sign))
elif dt[-1] == 'Z':
return datetime.strptime(dt, fmt + 'Z')
return datetime.strptime(dt, fmt)
কিন্তু এটি নেতিবাচক সময় অঞ্চলগুলিতে কাজ করে না। এটি যাইহোক আমি পাইথন ৩..3.৩ এ ভালভাবে কাজ করেছি:
from datetime import datetime
def to_datetime_tz(dt): # type: (str) -> datetime
fmt = '%Y-%m-%dT%H:%M:%S.%f'
if dt[-6] in frozenset(('+', '-')):
return datetime.strptime(dt, fmt + '%z')
elif dt[-1] == 'Z':
return datetime.strptime(dt, fmt + 'Z')
return datetime.strptime(dt, fmt)
কিছু পরীক্ষা, নোট করুন যে আউট শুধুমাত্র মাইক্রোসেকেন্ডের যথার্থতার দ্বারা পৃথক হয়। আমার মেশিনে যথাযথতার 6 টি সংখ্যক পাওয়া গেছে, তবে ওয়াইএমএমভি:
for dt_in, dt_out in (
('2019-03-11T08:00:00.000Z', '2019-03-11T08:00:00'),
('2019-03-11T08:00:00.000+11:00', '2019-03-11T08:00:00+11:00'),
('2019-03-11T08:00:00.000-11:00', '2019-03-11T08:00:00-11:00')
):
isoformat = to_datetime_tz(dt_in).isoformat()
assert isoformat == dt_out, '{} != {}'.format(isoformat, dt_out)
frozenset(('+', '-'))
? একটি সাধারণ টুপল ('+', '-')
একই জিনিস সম্পাদন করতে সক্ষম হওয়া উচিত নয় ?