আমি কীভাবে একটি আইএসও 8601- ফর্ম্যাট করা তারিখ পার্স করব?


642

পাইথনের ধরণের মতো আমাকে আরএফসি 3339 স্ট্রিং পার্স করতে হবে ।"2008-09-03T20:56:35.450686Z"datetime

আমি strptimeপাইথন স্ট্যান্ডার্ড লাইব্রেরিতে পেয়েছি , তবে এটি খুব সুবিধাজনক নয়।

এই কাজ করতে সবচেয়ে ভালো উপায় কি?


6
পাইথন বাগ: ইস্যু 15873
jfs


3
পরিষ্কার হতে হবে: আইএসও 8601 হ'ল প্রধান মান। আরএফসি 3339 হ'ল আইএসও 8601 এর একটি স্ব-ঘোষিত "প্রোফাইল" যা আইএসও 8601 বিধিগুলিকে কিছু বুদ্ধিমান ওভাররাইড করে
বাসিল বাউর্ক

3
আইসোফর্ম্যাট () বিবর্তনের জন্য নীচে পাইথন 3.7 + সমাধানটি মিস করবেন না
ব্র্যাড এম

2
এই প্রশ্নটি লিঙ্কযুক্ত পোস্টে ডুপ হিসাবে বন্ধ করা উচিত নয়। যেহেতু এটি একটি আইএসও 8601 টাইম স্ট্রিংকে পার্স করতে বলছে (যা পাইথনের পূর্বে 3.7 এর আগে সমর্থিত ছিল না) এবং অন্যটি একটি অপ্রচলিত পদ্ধতি ব্যবহার করে একটি ডেটটাইম অবজেক্টকে একটি যুগের স্ট্রিংয়ে ফর্ম্যাট করে।
abccd

উত্তর:


462

পাইথন-ডেটুটিল প্যাকেজটি কেবল প্রশ্নের মতোই আরএফসি 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


75
অলস, এটি মাধ্যমে ইনস্টল python-dateutilনা dateutil, তাই: pip install python-dateutil
cod3monk3y

29
সতর্কতা অবলম্বন করুন যে dateutil.parserইচ্ছাকৃতভাবে হ্যাকি: এটি ফর্ম্যাটটি অনুমান করার চেষ্টা করে এবং অস্পষ্ট ক্ষেত্রে অনিবার্য অনুমানগুলি (কেবলমাত্র হাতে কাস্টমাইজযোগ্য) করে। সুতরাং আপনার যদি অজানা ফর্ম্যাটটির ইনপুট পার্স করার প্রয়োজন হয় এবং মাঝে মাঝে ভুল প্রচার সহ্য করার পক্ষে ঠিক থাকে তবে এটি ব্যবহার করুন।
আইভান_পোজদেদেভ

2
একমত। একটি উদাহরণ 9999 এর একটি "তারিখ" কেটে যাচ্ছে This এটি ডেটটাইম (9999, বর্তমান মাস, বর্তমান দিন) হিসাবে একই হবে। আমার দৃষ্টিতে বৈধ তারিখ নয়।
টিম্বো

1
@ivan_pozdeev আপনি অ-অনুমানের পার্সিংয়ের জন্য কোন প্যাকেজের প্রস্তাব করবেন?
বিগুসাচ

2
@ আইভান_পোজদেদেভ মডিউলে একটি আপডেট রয়েছে যা iso8601 তারিখগুলি পড়ে: ডেটুটিল.ড্রেডহেডসকস.আইও
এএন

196

পাইথন ৩.7++ এ নতুন


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')

6
এটা বিরক্তিকর. কারণ একটিতে একটি datetimeথাকতে পারে tzinfoএবং এভাবে টাইমজোন আউটপুট পাওয়া যায় তবে datetime.fromisoformat()tzinfo কে পার্স করে না? বাগের মতো মনে হচ্ছে ..
হেন্ডি ইরওয়ান

20
ডকুমেন্টেশনে সেই নোটটি মিস করবেন না, এটি সমস্ত বৈধ আইএসও 8601 স্ট্রিং গ্রহণ করে না , কেবলমাত্র এটি দ্বারা উত্পাদিত isoformat। এটি "2008-09-03T20:56:35.450686Z"পিছনে থাকার কারণে প্রশ্নে উদাহরণটি গ্রহণ করে না Zতবে তা গ্রহণ করে "2008-09-03T20:56:35.450686"
ফ্লাইম

26
সঠিকভাবে সমর্থন করার Zজন্য ইনপুট স্ক্রিপ্টটি সংশোধন করা যেতে পারে date_string.replace("Z", "+00:00")
jox

7
মনে রাখবেন যে সেকেন্ডের জন্য এটি ঠিক 0, 3 বা 6 দশমিক জায়গাগুলি পরিচালনা করে। যদি ইনপুট ডেটাতে 1, 2, 4, 5, 7 বা আরও বেশি দশমিক স্থান থাকে তবে বিশ্লেষণ ব্যর্থ হবে!
ফেলেক

1
@ জেডিঅকটাউন এই উদাহরণটি পাইথনের ডেটটাইম লাইব্রেরি ব্যবহার করে, ডেটুটিলের পার্সার নয়। দশমিক স্থানগুলি এই পদ্ধতির সাথে 0, 3, বা 6 না হলে এটি আসলে ব্যর্থ হবে।
এ.সি.সি.ডি.

174

পাইথন ২.6+ এবং পাই 3 কে-তে নোট করুন,% f অক্ষর মাইক্রোসেকেন্ডগুলি ধরে।

>>> datetime.datetime.strptime("2008-09-03T20:56:35.450686Z", "%Y-%m-%dT%H:%M:%S.%fZ")

এখানে সমস্যা দেখুন


4
দ্রষ্টব্য - যদি নাইভ ডেটটাইমস ব্যবহার করা হয় - আমার মনে হয় আপনি কোনও টিজেড পাবেন না - জেড কিছু মিলতে পারে না।
ড্যানি স্ট্যাপল

24
এই উত্তরটি (এটির বর্তমান, সম্পাদিত আকারে) একটি নির্দিষ্ট ইউটিসি অফসেট ("জেড", যার অর্থ +00: 00) ফর্ম্যাট স্ট্রিংয়ে হার্ড কোডিংয়ের উপর নির্ভর করে। এটি একটি খারাপ ধারণা কারণ এটি কোনও ইউটিসি অফসেটের সাথে কোনও ডেটটাইমকে বিশ্লেষণ করতে ব্যর্থ হবে এবং ব্যতিক্রম বাড়াবে। আমার উত্তরটি দেখুন যা বর্ণনা করে যে কীভাবে আরএফসি 3339 strptimeকে পার্স করা বাস্তবে অসম্ভব।
মার্ক আমেরিকা

1
আমার ক্ষেত্রে% f জেডের চেয়ে মাইক্রোসেকেন্ডগুলিতে ধরা পড়েছে, datetime.datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%S.%f') সুতরাং এটি কৌশলটি করেছে
ashim888

পাই 3 কে মানে পাইথন 3000 ?!
রবিনো

2
IIRC @Robino, "পাইথন 3000" কি এখন পাইথন 3. হিসাবে পরিচিত হয় জন্য একটি পুরানো নাম
অ্যাকাউন্ট বর্জন করা

161

বেশ কয়েকটি উত্তর এখানে আরএফসি 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। পরিবর্তে এখানে বর্ণিত বর্ণিত আরও অনেক পদ্ধতির একটি ব্যবহার করুন।


79
এটা মনে হচ্ছে যে কেন স্ট্রপটাইমের আইএসও ফর্ম্যাট টাইমজোন তথ্যের জন্য নির্দেশনা নেই এবং কেন এটি পার্স করা যায় না। অবিশ্বাস্য।
সিএসবা তোথ

2
@ সিসাবাথ পুরোপুরি একমত - যদি আমার কিছুটা সময় কাটানোর থাকে তবে সম্ভবত আমি এটিকে ভাষায় যুক্ত করার চেষ্টা করব। অথবা আপনি এটি করতে পারতেন, যদি আপনি এত ঝোঁক থাকতেন - আমি দেখতে পাচ্ছি যে আপনি আমার থেকে আলাদা কিছু সি অভিজ্ঞতা অর্জন করেছেন।
মার্ক আমেরিকা

1
@ সিএসবাটোথ - অবিশ্বাস্য কেন? এটি বেশিরভাগ লোকের পক্ষে যথেষ্ট ভাল কাজ করে বা তারা যথেষ্ট পরিমাণে সহজ কাজ খুঁজে পেয়েছে। আপনার যদি বৈশিষ্ট্যটির প্রয়োজন হয় তবে এটি ওপেনসোর্স এবং আপনি এটি যুক্ত করতে পারেন। বা আপনার জন্য এটি করার জন্য কাউকে অর্থ প্রদান করুন। আপনার নির্দিষ্ট সমস্যাগুলি সমাধান করার জন্য কেন কারও নিজের অবসর সময় স্বেচ্ছাসেবক করা উচিত? উত্স আপনার সাথে থাকতে দিন।
পিটার এম - মনিকা

2
@ পিটারমাসিয়র অবিশ্বাস্য কারণ সাধারণত একজন আবিষ্কার করেন যে অজগরের জিনিসগুলি চিন্তাভাবনা ও পুরোপুরিভাবে প্রয়োগ করা হয়েছে। আমরা এই মনোযোগ দিয়ে বিশদভাবে নষ্ট হয়ে গিয়েছি এবং তাই যখন আমরা "অপ্রতিরোধ্য" ভাষাটির এমন কোনও কিছু জুড়ে হোঁচট খাই তখন আমরা আমাদের খেলনাগুলি প্রামের বাইরে ফেলে দেই, আমি এখনই এটি করতে যাচ্ছি। Whaaaaaaaaaa Whaa wahaaaaa :-(
Robino

2
strptime()পাইথন ৩.7-এ এখন এই উত্তরে অসম্ভব হিসাবে বর্ণিত সমস্ত কিছুই সমর্থন করে (টাইমজোন অফসেটে 'জেড' আক্ষরিক এবং ':')। দুর্ভাগ্যক্রমে, আর একটি কর্নারের কেস রয়েছে যা আরএফসি 3339 মৌলিকভাবে আইএসও 8601 এর সাথে অসামঞ্জস্যপূর্ণ করে তোলে, যথা, প্রাক্তনটি একটি নেতিবাচক নাল টাইমজোনকে অফসেট -00: 00 এবং পরে দেয় না।
সের্গি কোলেস্নিকভ

75

Iso8601 মডিউল চেষ্টা করুন ; এটা ঠিক এটা করে।

পাইথন.আর উইকিতে ওয়ার্কিং উইথটাইম পৃষ্ঠায় আরও কয়েকটি বিকল্প উল্লেখ করা হয়েছে ।


সাধারণ হিসাবেiso8601.parse_date("2008-09-03T20:56:35.450686Z")
পাকম্যান

3
প্রশ্নটি "আমি কীভাবে আইএসও 8601 তারিখগুলি পার্স করব" তা ছিল না, এটি ছিল "আমি কীভাবে এই সঠিক তারিখের ফর্ম্যাটটি পার্স করব"।
নিকোলাস রিলি

3
@tiktak ওপিকে "আমাকে এক্স এর মতো স্ট্রিংগুলি পার্স করা দরকার" জিজ্ঞাসা করা হয়েছিল এবং আমার জবাবটি, উভয় গ্রন্থাগার চেষ্টা করে অন্য একটি ব্যবহার করা উচিত, কারণ আইসো 8601 এর এখনও গুরুত্বপূর্ণ সমস্যা রয়েছে। এই জাতীয় প্রকল্পে আমার জড়িত হওয়া বা এর অভাব উত্তরের সাথে সম্পূর্ণ সম্পর্কিত নয়।
টোবিয়া

2
জেনে থাকুন যে iso8601 এর পাইপ সংস্করণ 2007 সাল থেকে আপডেট হয়নি এবং এর মধ্যে কয়েকটি গুরুতর বাগ রয়েছে যা অসামান্য। আমি নিজেই প্যাচগুলি নিয়ে কিছু সমালোচনামূলক প্রয়োগ করার পরামর্শ দিই বা ইতিমধ্যে এমন অনেক গিথব
কিথাকবার্থ

6
iso8601 , ওরফে পাইসো 8601 , ফেব্রুয়ারী 2014 হিসাবে সম্প্রতি আপডেট করা হয়েছে The সর্বশেষ সংস্করণটি আইএসও 8601 স্ট্রিংয়ের অনেক বিস্তৃত সেটকে সমর্থন করে। আমি আমার কিছু প্রকল্পে ভাল প্রভাব ব্যবহার করছি।
ডেভ হেইন

34
আমদানি পুনরায়, তারিখের সময়
গুলি = "2008-09-03T20: 56: 35.450686Z"
d = ডেটটাইম.ডেটটাইম (* মানচিত্র (int, re.split ('[^ \ d]', গুলি) [: - 1]))

73
আমি একমত নই, এটি ব্যবহারিকভাবে অপঠনযোগ্য এবং যতদূর আমি বলতে পারি যে জুলু (জেড) আমলে নেয় না যা টাইম জোনের ডেটা সরবরাহ করা সত্ত্বেও এই ডেটটাইমকে নিষ্পাপ করে তোলে।
umbrae

14
আমি এটি বেশ পঠনযোগ্য বলে মনে করি। আসলে, অতিরিক্ত প্যাকেজ ইনস্টল না করে রূপান্তরটি করা সম্ভবত সবচেয়ে সহজ এবং সর্বাধিক কার্যকর উপায় performing
টোবিয়া

2
এটি d = ডেটটাইম.ডেটটাইমের সমতুল্য (* মানচিত্র (int, re.split ('s D', s) [: - 1])) আমি মনে করি।
জুয়ান

4
একটি প্রকরণ:datetime.datetime(*map(int, re.findall('\d+', s))
jfs

3
টাইমজোন ছাড়াই একটি নিষ্পাপ ডেটটাইম অবজেক্টে এর ফলস্বরূপ? তাহলে ইউটিসি বিট অনুবাদে হারিয়ে যাবে?
w00t

32

আপনি কি সঠিক ত্রুটি পেয়েছেন? এটি কি নীচের মতো?

>>> 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)

10
আপনি কেবল জেড স্ট্রিপ করতে পারবেন না কারণ এর অর্থ সময় অঞ্চল এবং এটি ভিন্ন হতে পারে। আমার তারিখটি ইউটিসি টাইম জোনে রূপান্তর করা দরকার।
আলেকজান্ডার আর্তেমনকো

একটি সরল ডেটটাইম অবজেক্টের টাইমজোন সম্পর্কিত কোনও ধারণা নেই। যদি আপনার সমস্ত সময় "জেড" এ শেষ হয়, আপনি যে সমস্ত তারিখ পেয়েছেন তা ইউটিসি (জুলু সময়)।
tzot

যদি সময় অঞ্চল ছাড়া আর কিছু ""বা "Z", তাহলে এটি ঘন্টা / মিনিট, যা সরাসরি থেকে / DATETIME বস্তু থেকে বিয়োগ যোগ করা যেতে পারে একটি অফসেট হতে হবে। আপনি এটি পরিচালনা করতে একটি tzinfo সাবক্লাস তৈরি করতে পারেন, তবে সম্ভবত এটি পুনরুদ্ধার করা হয়নি।
সিঙ্গেলাইজেশন ইলিমিনেশন

8
অতিরিক্ত হিসাবে, "% f" হ'ল মাইক্রোসেকেন্ড স্পেসিফায়ার, সুতরাং একটি (টাইমজোন-নেভ) স্ট্রিমটাইম স্ট্রিংয়ের মতো দেখতে: "% Y-% m-% dT% H:% M:% S.% f"।
কোডলিবিটার

1
প্রদত্ত ডেটটাইম স্ট্রিংয়ের "জেড" ব্যতীত কোনও ইউটিসি অফসেট থাকলে এটি ব্যতিক্রম করবে raise এটি সম্পূর্ণ আরএফসি 3339 ফর্ম্যাটটিকে সমর্থন করে না এবং এটি অন্যদের কাছে নিকৃষ্ট উত্তর যা ইউটিসি অফসেটগুলি সঠিকভাবে পরিচালনা করে।
মার্ক আমেরিকা

24

পাইথন ৩.7 থেকে শুরু করে, স্ট্রিমটাইম ইউটিসি অফসেটে ( উত্স ) কোলন ডিলিমিটারগুলিকে সমর্থন করে । সুতরাং আপনি তারপর ব্যবহার করতে পারেন:

import datetime
datetime.datetime.strptime('2018-01-31T09:24:31.488670+00:00', '%Y-%m-%dT%H:%M:%S.%f%z')

সম্পাদনা করুন:

মার্টিজন দ্বারা চিহ্নিত হিসাবে, আপনি যদি আইসফর্ম্যাট () ব্যবহার করে ডেটটাইম অবজেক্ট তৈরি করেন তবে আপনি কেবল ডেটটাইম.ফর্মিসফর্ম্যাট () ব্যবহার করতে পারেন


4
কিন্তু 3.7, আপনি এছাড়াও আছে datetime.fromisoformat()যা হ্যান্ডলগুলি স্বয়ংক্রিয়ভাবে আপনার ইনপুট মত স্ট্রিং: datetime.datetime.isoformat('2018-01-31T09:24:31.488670+00:00')
মার্টিজন পিটারস

2
ভাল যুক্তি. আমি সম্মত, আমি ব্যবহার করার পরামর্শ দিই datetime.fromisoformat()এবংdatetime.isoformat()
Andreas Profous

19

এই দিনগুলিতে তীরটি তৃতীয় পক্ষের সমাধান হিসাবেও ব্যবহার করা যেতে পারে:

>>> import arrow
>>> date = arrow.get("2008-09-03T20:56:35.450686Z")
>>> date.datetime
datetime.datetime(2008, 9, 3, 20, 56, 35, 450686, tzinfo=tzutc())

6
তীরটি আইএসও 8601 যথাযথভাবে সমর্থন করে না: github.com/crsmithdev/arrow/issues/291
বক্স

1
অজগর-খেজুর ব্যবহার করুন - তীরের জন্য পাইথন-ডেটুটিল প্রয়োজন।
ডানিজেন

তীর এখন আইএসও 8601 সমর্থন করে। উল্লেখ করা বিষয়গুলি এখন বন্ধ।
Altus

17

কেবলমাত্র 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())

নথিপত্র


1
এটি কি ঠিক উপরে @Flimms উত্তর নয়?
লিও

1
আপনি কোথায় তাকে কয়েক সেকেন্ডের মধ্যে পার্স করতে দেখছেন? আমি এই নিবন্ধটি যুগের সময় পাওয়ার চেষ্টা করে খুঁজে পেয়েছি সুতরাং আমি অনুভব করেছি যে অন্য কেউও হবেন।
ব্লেয়ারজ

1
এটি আমার সিস্টেমে ইউটিসি নয় । পরিবর্তে, সেকেন্ডে আউটপুটটি ইউনিক্স যুগের সময় যেমন তারিখটি আমার স্থানীয় সময় অঞ্চলে।
এলিওট

1
এই উত্তরটি বগি এবং এটি গ্রহণ করা উচিত নয়। সম্ভবত পুরো প্রশ্নই সদৃশ হিসাবে চিহ্নিত করা উচিত stackoverflow.com/questions/11743019/...
tripleee

@ ট্রিপলি আসলে আমি কেবল কোডটি পরীক্ষা করেছি এবং এটি সঠিক উত্তরটি প্রত্যাবর্তন করে বলে মনে হচ্ছে: 455051100( epochconverter.com এ চেক করা হয়েছে ) ,,, যদি না আমি কিছু মিস করছি?
ব্লেয়ারজ 23

13

আপনি যদি ডেটুটিল ব্যবহার করতে না চান তবে আপনি এই ফাংশনটি ব্যবহার করে দেখতে পারেন:

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)

5
এই উত্তরটি একটি নির্দিষ্ট ইউটিসি অফসেট ("জেড", যার অর্থ +00: 00) এর পাসওয়ার্ড স্ট্রিংয়ে হার্ড কোডিংয়ের উপর নির্ভর করে strptime। এটি একটি খারাপ ধারণা কারণ এটি কোনও ইউটিসি অফসেটের সাথে কোনও ডেটটাইমকে বিশ্লেষণ করতে ব্যর্থ হবে এবং ব্যতিক্রম বাড়াবে। আমার উত্তর দেখুন যা বর্ণনা করে যে কীভাবে আরআরএফসি 3339 কে স্ট্রপটাইমের সাথে পার্স করা আসলে অসম্ভব।
মার্ক অ্যামেরি

1
এটি হার্ড-কোডড তবে এটি কেবলমাত্র আপনার যখন জুলুকে পার্স করতে হবে তবে এটি যথেষ্ট।
সাশা

1
@ আলেকসান্দার হ্যাঁ - যা হতে পারে যদি উদাহরণস্বরূপ, আপনি যদি জানেন যে জাভাস্ক্রিপ্টের toISOStringপদ্ধতিতে আপনার তারিখের স্ট্রিং তৈরি হয়েছিল । তবে এই উত্তরে জুলু সময়ের তারিখের সীমাবদ্ধতার কোনও উল্লেখ নেই, বা প্রশ্নটি ইঙ্গিত দেয়নি যে এটি যা প্রয়োজন, এবং কেবল এটি ব্যবহার করে dateutilযা পার্স করতে পারে তা প্রায় সমান সুবিধাজনক এবং কম সংকীর্ণ।
মার্ক আমেরিকা

11

আপনি যদি জ্যাঙ্গোর সাথে কাজ করছেন, এটি তারিখ পার্সী মডিউল সরবরাহ করে যা সময় অঞ্চল সহ আইএসও বিন্যাসের অনুরূপ ফর্ম্যাটগুলির একটি গোছা গ্রহণ করে।

আপনি যদি জ্যাঙ্গো ব্যবহার করছেন না এবং আপনি এখানে উল্লিখিত অন্য একটি গ্রন্থাগার ব্যবহার করতে না চান, আপনি সম্ভবত আপনার প্রকল্পে ডেটপার্সের জন্য জ্যাঙ্গো উত্স কোডটি মানিয়ে নিতে পারেন।


DateTimeFieldআপনি যখন স্ট্রিংয়ের মান সেট করেন তখন জাজানো এর ব্যবহার করে।
ডিজেভিজি

11

আমি আইএসও 8601 টাইমস্ট্যাম্পগুলি পার্স করার দ্রুততম উপায় হিসাবে সিসো 8601 পেয়েছি । নামটি যেমন বোঝায়, এটি সিতে প্রয়োগ করা হয়েছে

import ciso8601
ciso8601.parse_datetime('2014-01-09T21:48:00.921000+05:30')

GitHub রেপো README অন্যান্য উত্তর তালিকাবদ্ধ অন্যান্য লাইব্রেরি সব বনাম তাদের> 10x speedup দেখায়।

আমার ব্যক্তিগত প্রকল্পে প্রচুর আইএসও 8601 পার্সিং জড়িত। কেবল কলটি স্যুইচ করতে এবং 10x দ্রুত গতিতে সক্ষম হতে পেরে ভাল লাগছিল। :)

সম্পাদনা করুন: আমি তখন থেকে সিসো 8601 এর একজন রক্ষণাবেক্ষণকারী হয়েছি। এখন আগের চেয়ে দ্রুত!


এটি দেখতে দুর্দান্ত লাইব্রেরির মতো! গুগল অ্যাপ ইঞ্জিনে ISO8601 পার্সিং অনুকূলিতকরণের জন্য যারা চান তাদের জন্য, দুঃখের বিষয়, আমরা এটি ব্যবহার করতে পারি না কারণ এটি একটি সি লাইব্রেরি, তবে আপনার মানদণ্ডগুলি datetime.strptime()পরবর্তী তাত্পর্যপূর্ণ সমাধানটি দেখানোর জন্য অন্তর্দৃষ্টিপূর্ণ ছিল । সমস্ত তথ্য একসাথে রাখার জন্য ধন্যবাদ!
hamx0r

3
@ হ্যামএক্স0r, সচেতন হন যে datetime.strptime()কোনও সম্পূর্ণ আইএসও 8601 পার্সিং লাইব্রেরি নয়। আপনি পাইথন ৩.7 এ থাকলে আপনি সেই datetime.fromisoformat()পদ্ধতিটি ব্যবহার করতে পারেন যা কিছুটা নমনীয়। আপনি পার্সারগুলির এই আরও সম্পূর্ণ তালিকায় আগ্রহী হতে পারেন যা শীঘ্রই সিসো 8601 পুনরায় পড়াতে মার্জ করা উচিত।
মুভেরমায়ার

ciso8601 বেশ দুর্দান্ত কাজ করে তবে প্রথমে একটিকে "পিপ ইনস্টল পাইটজ" করতে হবে, কারণ পাইটজ নির্ভরতা ছাড়াই টাইম জোনের তথ্য সহ টাইমস্ট্যাম্প পার্স করতে পারে না। উদাহরণটি দেখতে পাবেন: dob = ciso8601. পার্স_ডেটটাইম (ফলাফল ['dob'] ['তারিখ'])
ডার্ক

2
@ ডার্ক, কেবল পাইথন 2 এ । এমনকি এটি পরবর্তী প্রকাশে অপসারণ করা উচিত
মুভেরমায়ার

8

এটি পাইথন ৩.২ এর পরে স্টাডলিবের জন্য কাজ করে (ধরে নিলে সমস্ত টাইমস্ট্যাম্পগুলি ইউটিসি):

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)

2
এই উত্তরটি একটি নির্দিষ্ট ইউটিসি অফসেট ("জেড", যার অর্থ +00: 00) এর পাসওয়ার্ড স্ট্রিংয়ে হার্ড কোডিংয়ের উপর নির্ভর করে strptime। এটি একটি খারাপ ধারণা কারণ এটি কোনও ইউটিসি অফসেটের সাথে কোনও ডেটটাইমকে বিশ্লেষণ করতে ব্যর্থ হবে এবং ব্যতিক্রম বাড়াবে। আমার উত্তর দেখুন যা বর্ণনা করে যে কীভাবে আরআরএফসি 3339 কে স্ট্রপটাইমের সাথে পার্স করা আসলে অসম্ভব।
মার্ক অ্যামেরি

1
তত্ত্বগতভাবে, হ্যাঁ, এটি ব্যর্থ হয়। অনুশীলনে, আমি কোনও আইএসও 8601-ফর্ম্যাট তারিখের মুখোমুখি হই নি যা জুলু সময়ে ছিল না। আমার খুব মাঝে মাঝে প্রয়োজনের জন্য, এটি দুর্দান্ত কাজ করে এবং কিছু বাহ্যিক লাইব্রেরিতে নির্ভর করে না।
বেঞ্জামিন রিগস 21

4
আপনি timezone.utcপরিবর্তে ব্যবহার করতে পারে timezone(timedelta(0))। এছাড়াও, কোডটি পাইথন ২.6++ (কমপক্ষে) তে কাজ করে যদি আপনি tzinfo অবজেক্ট সরবরাহ utcকরেন
jfs

আপনি যদি এটির মুখোমুখি হয়ে থাকেন তবে কিছু আসে যায় না, এটি অনুমানটির সাথে মেলে না।
ঘোষিত ঘোষক

আপনি %Zপাইথনের অতি সাম্প্রতিক সংস্করণগুলিতে টাইমজোন ব্যবহার করতে পারেন ।
স্পেনটিচি

7

আমি iso8601 ব্যবহারের লেখক। এটি গিটহাব বা পিপিআইতে পাওয়া যাবে । আপনি কীভাবে আপনার উদাহরণটি বিশ্লেষণ করতে পারেন তা এখানে:

>>> from iso8601utils import parsers
>>> parsers.datetime('2008-09-03T20:56:35.450686Z')
datetime.datetime(2008, 9, 3, 20, 56, 35, 450686)

6

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

11
ধন্যবাদ। এটি বিরক্তিকর. আমি এটা ভালোবাসি.
wchargin

1
কী অবিশ্বাস্য, দুর্দান্ত, সুন্দর হ্যাক! ধন্যবাদ!
হাভোক

6

আমি আইএসও 8601 স্ট্যান্ডার্ডের জন্য একটি পার্সার কোড করেছি এবং এটি গিটহাব: https://github.com/boxed/iso8601 এ রেখেছি । এই বাস্তবায়নটি পাইথনের ডেটটাইম মডিউলটির সমর্থিত তারিখের সীমা ছাড়ার মেয়াদ, বিরতি, পর্যায়ক্রমের বিরতি এবং তারিখ ব্যতীত স্পেসিফিকেশনের সমস্ত কিছুই সমর্থন করে।

টেস্ট অন্তর্ভুক্ত! : P: P



6

জ্যাঙ্গোর পার্স_ডেটটাইম () ফাংশন ইউটিসি অফসেটের সাথে তারিখগুলি সমর্থন করে:

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')

4

কারণ আইএসও 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

2

২. এক্স স্ট্যান্ডার্ড লাইব্রেরির সাথে কাজ করে এমন কিছুর জন্য চেষ্টা করুন:

calendar.timegm(time.strptime(date.split(".")[0]+"UTC", "%Y-%m-%dT%H:%M:%S%Z"))

ক্যালেন্ডার.টাইমগেমটি সময়.এমকেটাইমের অনুপস্থিত জিএম সংস্করণ।


1
এটি কেবল টাইমজোনকে উপেক্ষা করে '2013-01-28T14: 01: 01.335612-08: 00' -> ইউটিসি হিসাবে পার্স করা হয়েছে, পিডিটি নয়
গাটোটিগ্র্যাডো

2

অজানা তারিখের স্ট্রিংকে বিশ্লেষণ করলে পাইথন-ডেটুটিয়েল একটি ব্যতিক্রম ছুঁড়ে ফেলবে, তাই আপনি ব্যতিক্রমটি ধরতে চাইতে পারেন।

from dateutil import parser
ds = '2012-60-31'
try:
  dt = parser.parse(ds)
except ValueError, e:
  print '"%s" is an invalid date' % ds


2

অন্য একটি উপায় হল 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 পার্সার, ডেটুটি.এল পার্সার.আইসোপার্স উপলব্ধ।


1

ডেটটাইমের সমস্ত সম্ভাব্য আইএসও ফর্ম্যাটগুলির জন্য অ্যাকাউন্টে আমদানি করার জন্য দুর্দান্ত মার্ক আমেরির উত্তরের জন্য ধন্যবাদ :

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))

0
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


0

প্রাথমিকভাবে আমি চেষ্টা করেছি:

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(('+', '-'))? একটি সাধারণ টুপল ('+', '-')একই জিনিস সম্পাদন করতে সক্ষম হওয়া উচিত নয় ?
প্রহ্লাদ ইয়েরি

অবশ্যই, তবে এটি পুরোপুরি হ্যাশ লুকিংয়ের চেয়ে লিনিয়ার স্ক্যান নয়?
যেমন AT
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.