المُقدّمة
يمكن تمثيل البيانات في أشكال مختلفة - وطريقة مناسبة لتمثيل التواريخ والأوقات سلاسل. ومع ذلك ، للعمل مع هذه التواريخ والأوقات بطريقة حسابية (مثل حساب الفروق الزمنية ، وإضافة الوقت أو إزالته ، وما إلى ذلك) - نحتاج إلى تحويلها إلى datetime
موضوع.
أحد أكثر مصادر سلسلة التاريخ هي واجهات برمجة تطبيقات REST التي تعرض سلاسل محايدة ، ويمكننا بعد ذلك تحويلها إلى تنسيقات أخرى.
بالإضافة إلى ذلك - المناطق الزمنية هي صداع شائع عندما يتعلق الأمر بالعمل مع كائنات التاريخ والوقت ، لذلك سنحتاج إلى التفكير في ذلك أثناء التحويل أيضًا.
في هذا الدليل - سنلقي نظرة على كيفية تحويل تاريخ / وقت السلسلة إلى ملف
datetime
كائن في Python ، باستخدام المدمج فيdatetime
، ولكن أيضًا وحدات الطرف الثالث مثلdateutil
,arrow
ومايا ، تمثل المناطق الزمنية.
تحويل السلاسل باستخدام التاريخ والوقت
• التاريخ والوقت تتكون الوحدة النمطية من ثلاثة أنواع مختلفة من الكائنات: date
, time
و datetime
. date
الكائن يحمل التاريخ ، time
تمسك بالوقت ، و datetime
يحمل التاريخ والوقت!
import datetime
print(f'Current date/time: {datetime.datetime.now()}')
سيؤدي تشغيل هذا الرمز إلى:
Current date/time: 2022-12-01 10:27:03.929149
في حالة عدم تقديم تنسيق مخصص ، يتم استخدام تنسيق السلسلة الافتراضي ، أي أن تنسيق "2022-12-01 10: 27: 03.929149" في إعتماد ISO-8601 شكل (YYYY-MM-DDTHH: MM: SS.mmmmmm). إذا كانت سلسلة الإدخال لدينا لإنشاء ملف datetime
الكائن بنفس تنسيق ISO 8601 أو إذا كنت تعرف التنسيق الذي ستتلقاه مقدمًا ، فيمكننا بسهولة تحليله إلى datetime
موضوع:
import datetime
date_time_str = '2022-12-01 10:27:03.929149'
date_time_obj = datetime.datetime.strptime(date_time_str, '%Y-%m-%d %H:%M:%S.%f')
print('Date:', date_time_obj.date())
print('Time:', date_time_obj.time())
print('Date-time:', date_time_obj)
سيؤدي تشغيله إلى طباعة التاريخ والوقت والتاريخ - الوقت:
Date: 2022-12-01
Time: 10:27:03.929149
Date-time: 2022-12-01 10:27:03.929149
هنا ، نستخدم strptime()
الطريقة التي تقبل وسيطين:
- التاريخ المنسق بسلسلة
- شكل الوسيطة الأولى
تحديد تنسيق مثل هذا يجعل التحليل أسرع بكثير منذ ذلك الحين datetime
لا يحتاج إلى محاولة تفسير التنسيق من تلقاء نفسه ، وهو أغلى بكثير من الناحية الحسابية. القيمة المعادة من النوع datetime
.
في مثالنا ، "2022-12-01 10:27:03.929149"
هي سلسلة الإدخال و "%Y-%m-%d %H:%M:%S.%f"
هو تنسيق سلسلة التاريخ لدينا. عاد datetime
يتم تخزين القيمة على شكل date_time_obj
.
لأن هذا هو datetime
كائن ، يمكننا استدعاء date()
و time()
طرق مباشرة عليه. كما ترى من الإخراج ، فإنه يطبع جزء "التاريخ" و "الوقت" من سلسلة الإدخال!
تنسيق الرموز
الأمر يستحق أن نتوقف لحظة لفهمه رموز التنسيق - في "%Y-%m-%d %H:%M:%S.%f"
من قبل.
يمثل كل رمز مميزًا جزءًا مختلفًا من التاريخ والوقت ، مثل اليوم والشهر والسنة واليوم من الشهر أو الأسبوع ، وما إلى ذلك. قائمة الرموز المدعومة واسع بما يكفي لتمكين التنسيقات المتنوعة. بعض الأشياء الشائعة الاستخدام ، والتي استخدمناها أيضًا سابقًا هي:
%Y
: سنة (4 أرقام)%m
: شهر%d
: يوم من الشهر%H
: ساعة (24 ساعة)%M
: الدقائق%S
: ثواني%f
: نانو ثانية
ملحوظة: من المتوقع أن تكون جميع هذه الرموز المميزة ، باستثناء العام ، غير مبطن (أي أغسطس هو الشهر الثامن ، وهو غير مبطن حتى 08
).
استخدام strptime () تنسيق الرموز المميزة لتحويل سلسلة إلى تنسيق تاريخ ووقت مختلف
إذا كان تنسيق السلسلة معروفًا ، فيمكن تحليله بسهولة إلى ملف datetime
الكائن باستخدام strptime()
. دعنا نلقي نظرة على مثال غير تافه يترجم من تنسيق إلى آخر:
import datetime
date_time_str = 'Jul 17 2022 9:20AM'
date_time_obj = datetime.datetime.strptime(date_time_str, '%b %d %Y %I:%M%p')
print('Date:', date_time_obj.date())
print('Time:', date_time_obj.time())
print('Date-time:', date_time_obj)
كانت سلسلة الإدخال من تنسيق واحد - "17 يوليو 2022 9:20 ص". بمعرفة هذا التنسيق ، قمنا بتعيين العناصر المكونة إلى تنسيق ISO 8601 وقمنا بتحويله إلى تنسيق datetime
موضوع:
Date: 2022-07-17
Time: 09:20:00
Date-time: 2022-07-17 09:20:00
فيما يلي قائمة مختصرة بأوقات تنسيق السلسلة الشائعة والتنسيقات المقابلة لها لـ strptime()
:
"Jun 28 2018 at 7:40AM" -> "%b %d %Y at %I:%M%p"
"September 18, 2017, 22:19:55" -> "%B %d, %Y, %H:%M:%S"
"Sun,05/12/99,12:30PM" -> "%a,%d/%m/%y,%I:%M%p"
"Mon, 21 March, 2015" -> "%a, %d %B, %Y"
"2018-03-12T10:12:45Z" -> "%Y-%m-%dT%H:%M:%SZ"
يمكنك تحليل سلسلة التاريخ والوقت بأي تنسيق - طالما أنك تستخدم السلسلة الصحيحة من الرموز المميزة للتنسيق للإدخال الذي تتلقاه.
تحويل سلسلة إلى Datetime مع المناطق الزمنية
تصبح معالجة أوقات التاريخ أكثر تعقيدًا أثناء التعامل مع المناطق الزمنية. جميع الأمثلة المذكورة أعلاه حتى الآن ساذجة بالنسبة للمنطقة الزمنية. هذه معروفة باسم كائنات التاريخ والوقت الساذجة.
ومع ذلك، فإن datetime
كائنات تحتوي على حقل مخصص بالضبط لتخزين البيانات المتعلقة بالمنطقة الزمنية - tzinfo
:
import datetime as dt
dtime = dt.datetime.now()
print(dtime)
print(dtime.tzinfo)
• tzinfo
من المفترض أن يكون المجال datetime.timezone
كائن ، للدلالة على معلومات المنطقة الزمنية. إنه None
بشكل افتراضي ، ويشير إلى أن كائن التاريخ والوقت هو منطقة زمنية ساذجة. مكتبة خارجية شائعة جدًا للتعامل مع المناطق الزمنية هي pytz
. يمكنك ضبط بيتز كائنات مثل tzinfo
المجال أيضا.
إذا لم يكن لديك بالفعل - قم بتثبيته عبر:
$ pip install pytz
باستخدام PyTz ، يمكننا إنشاء نقطة ارتساء لأوقات معرفة المنطقة الزمنية ، مثل التوقيت العالمي المنسق (UTC):
import datetime as dt
import pytz
dtime = dt.datetime.now(pytz.utc)
print(dtime)
print(dtime.tzinfo)
الإخراج:
2022-12-01 02:07:41.960920+00:00
UTC
لم تعد الساعة 11 صباحًا ، ولكن الساعة 2 صباحًا ، لأننا حددنا المنطقة الزمنية قبل بضع ساعات! هذا يغير المنطقة الزمنية من التاريخ والوقت.
+00:00
هو الفرق بين الوقت المعروض والتوقيت العالمي المنسق (UTC) باعتباره نقطة ارتكاز التنسيق العالمي. لقد حددنا الوقت ليكون بالتوقيت العالمي المنسق ، لذا فإن الإزاحة هي 00:00
. هذا هو كائن يدرك المنطقة الزمنية.
وبالمثل ، يمكننا تبديل تفسير نفس التاريخ والوقت بين المناطق الزمنية. دعنا نحول سلسلة ، مثل "2022-06-29 17:08:00" إلى تاريخ ووقت وبعد ذلك تعريب إلى المنطقة الزمنية "America / New_York":
import datetime as dt
import pytz
date_time_str = '2022-06-29 17:08:00'
date_time_obj = dt.datetime.strptime(date_time_str, '%Y-%m-%d %H:%M:%S')
timezone = pytz.timezone('America/New_York')
timezone_date_time_obj = timezone.localize(date_time_obj)
print(timezone_date_time_obj)
print(timezone_date_time_obj.tzinfo)
ملحوظة: التعريب يحول التاريخ والوقت الساذج للمنطقة الزمنية إلى تاريخ ووقت مدركين للمنطقة الزمنية ، ويعامل المنطقة الزمنية على أنها المنطقة الزمنية المحلية. وهكذا ، فإن datetime يبقى كما هو، ولكن نظرًا لاختلاف المنطقة الزمنية ، لم تعد تمثل نفس النقطة الزمنية غير المرتبطة بالمناطق الزمنية.
نحصل على نفس الشيء قيمة التاريخ والوقت، تم التعديل بواسطة -04: 00 مقارنة بوقت UTC:
2022-06-29 17:08:00-04:00
America/New_York
الساعة 17:08 في طوكيو ليس نفس النقطة الزمنية الساعة 17:08 في نيويورك. الساعة 17:08 في طوكيو الساعة 3:08 بتوقيت نيويورك.
كيف تجد كل رموز المنطقة الزمنية / الأسماء المستعارة؟
للعثور على جميع المناطق الزمنية المتاحة ، قم بفحص ملف all_timezones
، وهي قائمة بجميع المناطق الزمنية المتاحة:
print(f'There are {len(pytz.all_timezones)} timezones in PyTzn')
for time_zone in pytz.all_timezones:
print(time_zone)
تحقق من دليلنا العملي العملي لتعلم Git ، مع أفضل الممارسات ، والمعايير المقبولة في الصناعة ، وورقة الغش المضمنة. توقف عن أوامر Googling Git وفي الواقع تعلم ذلك!
There are 594 timezones in PyTz
Africa/Abidjan
Africa/Accra
Africa/Addis_Ababa
Africa/Algiers
Africa/Asmara
Africa/Asmera
...
تغيير المنطقة الزمنية للتاريخ والوقت
يمكننا تحويل المنطقة الزمنية للمنطقة الزمنية datetime
من منطقة إلى أخرى ، بدلاً من تحديد موقع وقت وتاريخ ساذج من منطقة زمنية من خلال عدسة بعض المنطقة الزمنية.
هذا يختلف عن التوطين ، حيث يمثل التوطين نقطة زمنية مختلفة ، لكن تحويل المنطقة الزمنية لكائن ما يمثل نفس النقطة الزمنية ، من خلال عدسة مختلفة:
import datetime as dt
import pytz
timezone_nw = pytz.timezone('America/New_York')
nw_datetime_obj = dt.datetime.now(timezone_nw)
timezone_london = pytz.timezone('Europe/London')
london_datetime_obj = nw_datetime_obj.astimezone(timezone_london)
print('America/New_York:', nw_datetime_obj)
print('Europe/London:', london_datetime_obj)
أولاً ، أنشأنا كائنًا واحدًا للوقت والوقت باستخدام الوقت الحالي وقمنا بتعيينه على أنه المنطقة الزمنية "America / New_York". ثم استخدم ملف astimezone()
الطريقة ، لقد قمنا بتحويل هذا datetime
إلى المنطقة الزمنية "أوروبا / لندن". كلاهما datetime
ستطبع s قيمًا مختلفة ، باستخدام تعويض UTC كحلقة وصل مرجعية بينهما:
America/New_York: 2022-11-30 21:24:30.123400-05:00
Europe/London: 2022-12-01 02:24:30.123400+00:00
2:24 في اليوم التالي في لندن is نفس النقطة الزمنية كما في الساعة 21:24 في اليوم السابق في نيويورك لأن لندن تتقدم بخمس ساعات.
كما هو متوقع ، تختلف أوقات التاريخ حيث تفصل بينهما حوالي 5 ساعات.
تحويل سلسلة إلى Datetime باستخدام مكتبات الطرف الثالث
بيثون datetime
يمكن للوحدة النمطية تحويل جميع أنواع السلاسل المختلفة إلى ملف datetime
هدف. لكن المشكلة الرئيسية هي أنه من أجل القيام بذلك ، تحتاج إلى إنشاء سلسلة كود التنسيق المناسبة strptime()
يمكن أن يفهم. يستغرق إنشاء هذه السلسلة وقتًا ويجعل قراءة الكود أكثر صعوبة.
بدلاً من ذلك ، يمكننا استخدام مكتبات الطرف الثالث الأخرى لتسهيل الأمر.
في بعض الحالات ، تتمتع مكتبات الجهات الخارجية هذه أيضًا بدعم مدمج أفضل لمعالجة ومقارنة أوقات التاريخ ، وبعضها يحتوي على مناطق زمنية مدمجة ، لذلك لا تحتاج إلى تضمين حزمة PyTz إضافية.
دعنا نلقي نظرة على بعض هذه المكتبات في الأقسام التالية.
تحويل String إلى Datetime باستخدام dateutil
• وحدة داتوتيل هو امتداد ل datetime
وحدة. ميزة واحدة هي أننا لسنا بحاجة إلى تمرير أي كود تحليل لتحليل سلسلة!
لتحويل سلسلة تلقائيًا إلى تاريخ ووقت بدون رمز تنسيق باستخدام Python dateutil
:
from dateutil.parser import parse
datetime = parse('2018-06-29 22:21:41')
print(datetime)
هذه parse
ستعمل الوظيفة على تحليل السلسلة تلقائيًا! ليس عليك تضمين أي سلسلة تنسيق. دعنا نحاول تحليل أنواع مختلفة من السلاسل باستخدام dateutil
:
from dateutil.parser import parse
date_array = [
'2018-06-29 08:15:27.243860',
'Jun 28 2018 7:40AM',
'Jun 28 2018 at 7:40AM',
'September 18, 2017, 22:19:55',
'Sun, 05/12/1999, 12:30PM',
'Mon, 21 March, 2015',
'2018-03-12T10:12:45Z',
'2018-06-29 17:08:00.586525+00:00',
'2018-06-29 17:08:00.586525+05:00',
'Tuesday , 6th September, 2017 at 4:30pm'
]
for date in date_array:
print('Parsing: ' + date)
dt = parse(date)
print(dt.date())
print(dt.time())
print(dt.tzinfo)
print('n')
الإخراج:
Parsing: 2018-06-29 08:15:27.243860
2018-06-29
08:15:27.243860
None
Parsing: Jun 28 2018 7:40AM
2018-06-28
07:40:00
None
Parsing: Jun 28 2018 at 7:40AM
2018-06-28
07:40:00
None
Parsing: September 18, 2017, 22:19:55
2017-09-18
22:19:55
None
Parsing: Sun, 05/12/1999, 12:30PM
1999-05-12
12:30:00
None
Parsing: Mon, 21 March, 2015
2015-03-21
00:00:00
None
Parsing: 2018-03-12T10:12:45Z
2018-03-12
10:12:45
tzutc()
Parsing: 2018-06-29 17:08:00.586525+00:00
2018-06-29
17:08:00.586525
tzutc()
Parsing: 2018-06-29 17:08:00.586525+05:00
2018-06-29
17:08:00.586525
tzoffset(None, 18000)
Parsing: Tuesday , 6th September, 2017 at 4:30pm
2017-09-06
16:30:00
None
يمكنك أن ترى أنه يمكن تحليل أي نوع من الخيوط تقريبًا بسهولة باستخدام امتداد dateutil
وحدة.
على الرغم من أن هذا مناسب ، تذكر من وقت سابق أن الاضطرار إلى التنبؤ بالتنسيق يجعل الشفرة أبطأ بكثير ، لذلك إذا كنت تتطلب أداءً عاليًا ، فقد لا يكون هذا هو الأسلوب الصحيح لتطبيقك.
تحويل String إلى Datetime باستخدام Maya
مايا كما أنه يجعل من السهل جدًا تحليل سلسلة وتغيير المناطق الزمنية. لتحويل سلسلة بسهولة باستخدام Python Maya:
import maya
dt = maya.parse('2018-04-29T17:45:25Z').datetime()
print(dt.date())
print(dt.time())
print(dt.tzinfo)
الإخراج:
2018-04-29
17:45:25
UTC
لتحويل الوقت إلى منطقة زمنية مختلفة:
import maya
dt = maya.parse('2018-04-29T17:45:25Z').datetime(to_timezone='America/New_York', naive=False)
print(dt.date())
print(dt.time())
print(dt.tzinfo)
الإخراج:
2018-04-29
13:45:25
America/New_York
الآن أليس هذا سهل الاستخدام؟ دعنا نجرب maya
بنفس مجموعة السلاسل التي استخدمناها مع dateutil
:
import maya
date_array = [
'2018-06-29 08:15:27.243860',
'Jun 28 2018 7:40AM',
'Jun 28 2018 at 7:40AM',
'September 18, 2017, 22:19:55',
'Sun, 05/12/1999, 12:30PM',
'Mon, 21 March, 2015',
'2018-03-12T10:12:45Z',
'2018-06-29 17:08:00.586525+00:00',
'2018-06-29 17:08:00.586525+05:00',
'Tuesday , 6th September, 2017 at 4:30pm'
]
for date in date_array:
print('Parsing: ' + date)
dt = maya.parse(date).datetime()
print(dt)
الإخراج:
Parsing: 2018-06-29 08:15:27.243860
2018-06-29 08:15:27.243860+00:00
Parsing: Jun 28 2018 7:40AM
2018-06-28 07:40:00+00:00
Parsing: Jun 28 2018 at 7:40AM
2018-06-28 07:40:00+00:00
Parsing: September 18, 2017, 22:19:55
2017-09-18 22:19:55+00:00
Parsing: Sun, 05/12/1999, 12:30PM
1999-05-12 12:30:00+00:00
Parsing: Mon, 21 March, 2015
2015-03-21 00:00:00+00:00
Parsing: 2018-03-12T10:12:45Z
2018-03-12 10:12:45+00:00
Parsing: 2018-06-29 17:08:00.586525+00:00
2018-06-29 17:08:00.586525+00:00
Parsing: 2018-06-29 17:08:00.586525+05:00
2018-06-29 12:08:00.586525+00:00
Parsing: Tuesday , 6th September, 2017 at 4:30pm
2017-09-06 16:30:00+00:00
كما ترى ، تم تحليل جميع تنسيقات التاريخ بنجاح!
إذا لم نقدم معلومات المنطقة الزمنية ، فسيحولها تلقائيًا إلى التوقيت العالمي المنسق (UTC). لذا ، من المهم أن نلاحظ أننا يجب توفير to_timezone
و naive
المعلمات إذا لم يكن الوقت بالتوقيت العالمي المنسق (UTC).
تحويل سلسلة إلى Datetime مع Arrow
سهم هي مكتبة أخرى للتعامل مع التاريخ والوقت في بايثون. ومثل مع maya
، فإنه يحدد أيضًا تنسيق التاريخ والوقت تلقائيًا. بمجرد تفسيره ، فإنه يعيد Python datetime
الكائن من arrow
موضوع.
لتحويل سلسلة بسهولة إلى datetime باستخدام Python arrow
:
import arrow
dt = arrow.get('2018-04-29T17:45:25Z')
print(dt.date())
print(dt.time())
print(dt.tzinfo)
الإخراج:
2018-04-29
17:45:25
tzutc()
وهنا كيف يمكنك استخدام arrow
لتحويل المناطق الزمنية باستخدام to()
الأسلوب:
import arrow
dt = arrow.get('2018-04-29T17:45:25Z').to('America/New_York')
print(dt)
print(dt.date())
print(dt.time())
الإخراج:
2018-04-29T13:45:25-04:00
2018-04-29
13:45:25
كما ترى ، يتم تحويل سلسلة التاريخ والوقت إلى منطقة "America / New_York".
الآن ، دعنا نستخدم نفس مجموعة السلاسل التي استخدمناها أعلاه:
import arrow
date_array = [
'2018-06-29 08:15:27.243860',
'2018-03-12T10:12:45Z',
'2018-06-29 17:08:00.586525+00:00',
'2018-06-29 17:08:00.586525+05:00',
]
for date in date_array:
dt = arrow.get(date)
print('Parsing: ' + date)
print(dt)
ستفشل هذه الشفرة في سلاسل التاريخ والوقت التي تم التعليق عليها ، والتي تعد أكثر من نصف أمثلةنا. سيكون إخراج السلاسل الأخرى كما يلي:
Parsing: 2018-06-29 08:15:27.243860
2018-06-29T08:15:27.243860+00:00
Parsing: 2018-03-12T10:12:45Z
2018-03-12T10:12:45+00:00
Parsing: 2018-06-29 17:08:00.586525+00:00
2018-06-29T17:08:00.586525+00:00
Parsing: 2018-06-29 17:08:00.586525+05:00
2018-06-29T17:08:00.586525+05:00
من أجل تحليل سلاسل التاريخ والوقت التي تم التعليق عليها بشكل صحيح ، ستحتاج إلى تمرير المقابل رموز التنسيق لإعطاء أدلة للمكتبة حول كيفية تحليلها.
وفي الختام
في هذه المقالة ، أظهرنا طرقًا مختلفة لتحليل سلسلة نصية إلى ملف datetime
كائن في بايثون. يمكنك إما اختيار Python الافتراضي datetime
مكتبة أو أي من مكتبات الطرف الثالث المذكورة في هذه المقالة ، من بين العديد من المكتبات الأخرى.
المشكلة الرئيسية مع الافتراضي datetime
الحزمة هي أننا نحتاج إلى تحديد كود التحليل يدويًا لجميع تنسيقات سلسلة التاريخ والوقت تقريبًا. لذلك ، إذا تغير تنسيق السلسلة في المستقبل ، فمن المحتمل أن تضطر إلى تغيير الكود أيضًا. لكن العديد من مكتبات الجهات الخارجية ، مثل تلك المذكورة هنا ، تتعامل معها تلقائيًا.
هناك مشكلة أخرى نواجهها وهي التعامل مع المناطق الزمنية. أفضل طريقة للتعامل معها هي دائمًا تخزين الوقت في قاعدة البيانات الخاصة بك بتنسيق UTC ثم تحويله إلى المنطقة الزمنية المحلية للمستخدم عند الحاجة.
هذه المكتبات ليست جيدة فقط لتحليل السلاسل ، ولكن يمكن استخدامها للعديد من الأنواع المختلفة من العمليات المتعلقة بالتاريخ والوقت. أود أن أشجعك على الاطلاع على المستندات لمعرفة الوظائف بالتفصيل.