تبدیل رشته ها به datetime در پایتون

معرفی

داده ها را می توان به اشکال مختلف نشان داد - و یک راه مناسب برای نمایش تاریخ و زمان است رشته های. با این حال، برای کار با این تاریخ ها و زمان ها به صورت حسابی (مانند محاسبه اختلاف زمانی، اضافه یا حذف زمان و غیره) - باید آنها را به یک تبدیل کنیم. datetime هدف - شی.

یکی از رایج ترین منابع زمان های تاریخ با قالب رشته ای APIهای REST هستند که رشته‌های آگنوستیک را برمی‌گردانند و سپس می‌توانیم آن‌ها را به فرمت‌های دیگر تبدیل کنیم.

علاوه بر این - مناطق زمانی یک سردرد رایج در هنگام کار با اشیاء زمان تاریخ هستند، بنابراین باید در هنگام تبدیل نیز به آن فکر کنیم.

در این راهنما - ما نگاهی به نحوه تبدیل تاریخ/زمان رشته به a خواهیم داشت datetime شی در پایتون، با استفاده از داخلی datetime ماژول، بلکه ماژول های شخص ثالث مانند dateutil, arrow و مایا، حسابداری برای مناطق زمانی.

تبدیل رشته ها با استفاده از timetime

La زمان قرار ماژول از سه نوع شی مختلف تشکیل شده است: 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() Format Tokens برای تبدیل رشته به فرمت های مختلف تاریخ

اگر فرمت یک رشته مشخص باشد، می توان آن را به راحتی به a تجزیه کرد 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)

رشته ورودی یک قالب بود - "Jul 17 2022 9:20AM". با دانستن این فرمت، عناصر تشکیل دهنده را به فرمت 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 با Timezones

هنگام برخورد با مناطق زمانی، رسیدگی به تاریخ-زمان‌ها پیچیده‌تر می‌شود. همه مثال‌های بالا تا کنون نسبت به منطقه زمانی ساده‌لوح هستند. اینها به عنوان شناخته می شوند اشیاء ساده تاریخ.

با این حال، datetime اشیاء دقیقاً حاوی یک فیلد برای ذخیره داده های مربوط به منطقه زمانی هستند - tzinfo:

import datetime as dt
dtime = dt.datetime.now()

print(dtime) 
print(dtime.tzinfo) 

La tzinfo فیلد به معنای a است datetime.timezone شی، نشان دهنده اطلاعات منطقه زمانی است. این است None به طور پیش‌فرض، و نشان می‌دهد که شی datetime یک منطقه زمانی ساده است. یک کتابخانه خارجی بسیار رایج برای مدیریت مناطق زمانی است pytz. می توانید تنظیم کنید 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 به عنوان لنگر هماهنگی جهانی است. ما زمان را در UTC تنظیم کرده‌ایم، بنابراین افست است 00:00. این یک است شیء آگاه از منطقه زمانی.

به طور مشابه، می‌توانیم تفسیر همان تاریخ را بین مناطق زمانی تغییر دهیم. بیایید یک رشته، مانند "2022-06-29 17:08:00" را به تاریخ و سپس تبدیل کنیم بومی سازی به منطقه زمانی «آمریکا/نیویورک» بروید:

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)

توجه داشته باشید: بومی سازی یک تاریخ زمان ساده برای منطقه زمانی را به زمان تاریخی آگاه از منطقه زمانی تبدیل می کند و منطقه زمانی را به عنوان منطقه زمانی محلی در نظر می گیرد. بنابراین تاریخ تاریخ ثابت می ماند، اما با توجه به منطقه زمانی متفاوت، دیگر همان نقطه زمانی بدون محدودیت از مناطق زمانی را نشان نمی دهد.

ما هم همین را می گیریم مقدار تاریخ، جبران شده توسط -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 را با بهترین روش ها، استانداردهای پذیرفته شده در صنعت و برگه تقلب شامل بررسی کنید. دستورات Google Git را متوقف کنید و در واقع یاد گرفتن آی تی!

There are 594 timezones in PyTz

Africa/Abidjan
Africa/Accra
Africa/Addis_Ababa
Africa/Algiers
Africa/Asmara
Africa/Asmera
...

منطقه زمانی Datetime را تغییر دهید

ما می توانیم منطقه زمانی را به یک منطقه زمانی آگاه تبدیل کنیم 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)

ابتدا یک شی datetime با زمان فعلی ایجاد کردیم و آن را به عنوان منطقه زمانی "America/New_York" تنظیم کردیم. سپس با استفاده از astimezone() روش، ما این را تبدیل کرده ایم datetime به منطقه زمانی «اروپا/لندن». هر دو datetimes مقادیر مختلفی را با استفاده از UTC offset به عنوان پیوند مرجع بین آنها چاپ می کند:

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 ساعت جلوتر است.

همانطور که انتظار می رود، تاریخ زمان ها متفاوت است زیرا حدود 5 ساعت از هم فاصله دارند.

با استفاده از کتابخانه های شخص ثالث، رشته را به زمان تاریخ تبدیل کنید

پایتون datetime ماژول می تواند انواع مختلف رشته ها را به a تبدیل کند datetime هدف - شی. اما مشکل اصلی این است که برای انجام این کار باید رشته کد قالب بندی مناسبی را ایجاد کنید strptime() می تواند درک کند. ایجاد این رشته زمان می برد و خواندن کد را سخت تر می کند.

در عوض، می‌توانیم از کتابخانه‌های شخص ثالث دیگر برای آسان‌تر کردن آن استفاده کنیم.

در برخی موارد، این کتابخانه‌های شخص ثالث نیز پشتیبانی داخلی بهتری برای دستکاری و مقایسه تاریخ‌زمان‌ها دارند، و برخی حتی دارای مناطق زمانی داخلی هستند، بنابراین نیازی به اضافه کردن بسته PyTz اضافی ندارید.

بیایید نگاهی به چند مورد از این کتابخانه ها در بخش های بعدی بیاندازیم.

تبدیل رشته به Datetime با dateutil

La ماژول dateutil یک فرمت به است datetime مدول. یک مزیت این است که برای تجزیه یک رشته نیازی به ارسال کد تجزیه ای نداریم!

برای تبدیل خودکار یک رشته به 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 ماژول

در حالی که این راحت است، از قبل به یاد بیاورید که پیش بینی فرمت کد را بسیار کندتر می کند، بنابراین اگر کد شما به کارایی بالایی نیاز دارد، ممکن است این روش برای برنامه شما مناسب نباشد.

تبدیل رشته به Datetime با 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 تبدیل کنید

فلش کتابخانه دیگری برای رسیدگی به تاریخ در پایتون است. و مثل قبل با maya، همچنین قالب تاریخ را به طور خودکار مشخص می کند. پس از تفسیر، پایتون را برمی گرداند datetime شی از arrow هدف - شی.

برای تبدیل آسان یک رشته به تاریخ با استفاده از پایتون 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

به منظور تجزیه صحیح رشته های تاریخ-زمان که نظر داده شده است، باید متن مربوطه را ارسال کنید فرمت نشانه ها تا به کتابخانه سرنخ هایی در مورد چگونگی تجزیه آن بدهد.

نتیجه

در این مقاله راه های مختلفی برای تجزیه رشته به a نشان داده ایم datetime شی در پایتون شما هم می توانید پایتون پیش فرض را انتخاب کنید datetime کتابخانه یا هر یک از کتابخانه های شخص ثالث ذکر شده در این مقاله، در میان بسیاری دیگر.

مشکل اصلی پیش فرض datetime بسته این است که ما باید کد تجزیه را به صورت دستی برای تقریباً تمام قالب‌های رشته تاریخ-زمان مشخص کنیم. بنابراین، اگر قالب رشته شما در آینده تغییر کند، احتمالاً باید کد خود را نیز تغییر دهید. اما بسیاری از کتابخانه های شخص ثالث، مانند موارد ذکر شده در اینجا، به طور خودکار آن را مدیریت می کنند.

یکی دیگر از مشکلاتی که ما با آن روبرو هستیم، برخورد با مناطق زمانی است. بهترین راه برای رسیدگی به آنها این است که همیشه زمان را در پایگاه داده خود با فرمت UTC ذخیره کنید و در صورت نیاز آن را به منطقه زمانی محلی کاربر تبدیل کنید.

این کتابخانه ها نه تنها برای تجزیه رشته ها خوب هستند، بلکه می توانند برای انواع مختلفی از عملیات مربوط به تاریخ و زمان استفاده شوند. من شما را تشویق می کنم که اسناد را مرور کنید تا عملکردها را با جزئیات بیاموزید.

تمبر زمان:

بیشتر از Stackabuse