Chuyển chuỗi thành datetime trong Python

Giới thiệu

Dữ liệu có thể được biểu diễn dưới nhiều dạng khác nhau – và một cách thuận tiện để biểu diễn ngày và giờ là dây. Tuy nhiên, để làm việc với những ngày và giờ này theo kiểu số học (chẳng hạn như tính chênh lệch múi giờ, thêm hoặc bớt thời gian, v.v.) – chúng ta cần chuyển đổi chúng thành dạng datetime vật.

Một trong những nguồn phổ biến nhất của thời gian định dạng chuỗi là các API REST trả về các chuỗi bất khả tri, sau đó chúng ta có thể chuyển đổi sang các định dạng khác.

Ngoài ra – các múi giờ là một vấn đề đau đầu phổ biến khi làm việc với các đối tượng ngày giờ, vì vậy chúng ta cũng cần phải suy nghĩ về điều đó trong khi chuyển đổi.

Trong hướng dẫn này – chúng ta sẽ xem xét cách chuyển đổi ngày/giờ chuỗi thành datetime đối tượng trong Python, sử dụng tích hợp sẵn datetime mô-đun, mà cả các mô-đun của bên thứ ba như dateutil, arrow và Maya, chiếm các múi giờ.

Chuyển đổi chuỗi Sử dụng datetime

Sản phẩm ngày giờ module bao gồm ba loại đối tượng khác nhau: date, timedatetime. Các date đối tượng giữ ngày, time giữ thời gian, và datetime giữ cả ngày và giờ!

import datetime
print(f'Current date/time: {datetime.datetime.now()}')

Chạy mã này sẽ dẫn đến:

Current date/time: 2022-12-01 10:27:03.929149

Khi không có định dạng tùy chỉnh nào được cung cấp, định dạng chuỗi mặc định sẽ được sử dụng, tức là định dạng cho “2022-12-01 10:27:03.929149” nằm trong ISO 8601 định dạng (YYYY-MM-DDTHH:MM:SS.mmmmmm). Nếu chuỗi đầu vào của chúng tôi để tạo một datetime đối tượng có cùng định dạng ISO 8601 hoặc nếu bạn biết trước định dạng bạn sẽ nhận được, chúng tôi có thể dễ dàng phân tích cú pháp đó thành một datetime vật:

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)

Chạy nó sẽ in ngày, giờ và ngày giờ:

Date: 2022-12-01
Time: 10:27:03.929149
Date-time: 2022-12-01 10:27:03.929149

Ở đây, chúng tôi sử dụng strptime() phương thức, chấp nhận hai đối số:

  • Ngày định dạng chuỗi
  • Định dạng của đối số đầu tiên

Chỉ định định dạng như thế này giúp phân tích cú pháp nhanh hơn nhiều vì datetime không cần phải tự mình thử và giải thích định dạng, điều này tốn kém hơn nhiều về mặt tính toán. Giá trị trả về là kiểu datetime.

Trong ví dụ của chúng tôi, "2022-12-01 10:27:03.929149" là chuỗi đầu vào và "%Y-%m-%d %H:%M:%S.%f" là định dạng của chuỗi ngày của chúng tôi. Sự trở lại datetime giá trị được lưu trữ dưới dạng date_time_obj.

Vì đây là một datetime đối tượng, chúng ta có thể gọi date()time() các phương thức trực tiếp trên đó. Như bạn có thể thấy từ đầu ra, nó in phần 'ngày' và 'thời gian' của chuỗi đầu vào!

Định dạng mã thông báo

Thật đáng để dành một chút thời gian để hiểu định dạng mã thông báo - các "%Y-%m-%d %H:%M:%S.%f" từ trước đó.

Mỗi mã thông báo đại diện cho một phần khác nhau của thời gian ngày, như ngày, tháng, năm, ngày trong tháng hoặc tuần, v.v. danh sách các mã thông báo được hỗ trợ là đủ rộng để cho phép định dạng khác nhau. Một số cái thường được sử dụng, mà chúng tôi cũng đã sử dụng trước đó là:

  • %Y: Năm (4 chữ số)
  • %m: Tháng
  • %d: Ngày trong tháng
  • %H: Giờ (24 giờ)
  • %M: Phút
  • %S: Giây
  • %f: Micro giây

Lưu ý: Tất cả các mã thông báo này, ngoại trừ năm, dự kiến ​​sẽ không được đệm (tức là tháng 8 là tháng thứ XNUMX và không được đệm cho 08).

Sử dụng mã thông báo định dạng strptime() để chuyển đổi chuỗi thành định dạng ngày giờ khác nhau

Nếu định dạng của một chuỗi được biết, nó có thể dễ dàng được phân tích cú pháp thành một datetime đối tượng sử dụng strptime(). Chúng ta hãy xem một ví dụ không tầm thường dịch từ định dạng này sang định dạng khác:

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)

Chuỗi đầu vào có một định dạng – “Jul 17 2022 9:20AM”. Khi biết định dạng này, chúng tôi đã ánh xạ các yếu tố cấu thành sang định dạng ISO 8601 và chuyển đổi nó thành định dạng datetime vật:

Date: 2022-07-17
Time: 09:20:00
Date-time: 2022-07-17 09:20:00

Dưới đây là danh sách ngắn các mốc thời gian định dạng chuỗi phổ biến và định dạng tương ứng của chúng cho 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"

Bạn có thể phân tích cú pháp chuỗi ngày-giờ ở bất kỳ định dạng nào – miễn là bạn sử dụng đúng chuỗi mã thông báo định dạng cho đầu vào bạn đang nhận.

Chuyển đổi Chuỗi thành Ngày giờ với Múi giờ

Xử lý ngày giờ trở nên phức tạp hơn trong khi xử lý múi giờ. Tất cả các ví dụ trên cho đến nay đều ngây thơ đối với múi giờ. Chúng được gọi là đối tượng datetime ngây thơ.

Tuy nhiên, datetime các đối tượng chứa một trường chính xác để lưu trữ dữ liệu liên quan đến múi giờ – tzinfo:

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

print(dtime) 
print(dtime.tzinfo) 

Sản phẩm tzinfo trường có nghĩa là một datetime.timezone đối tượng, biểu thị thông tin múi giờ. nó là None theo mặc định và biểu thị rằng đối tượng datetime không có múi giờ. Một thư viện bên ngoài rất phổ biến để xử lý các múi giờ là pytz. Bạn có thể đặt PyTz các đối tượng như tzinfo lĩnh vực này quá.

Nếu bạn chưa có nó – hãy cài đặt nó qua:

$ pip install pytz

Sử dụng PyTz, chúng ta có thể tạo một mỏ neo cho thời gian biểu nhận biết múi giờ, chẳng hạn như UTC:

import datetime as dt
import pytz

dtime = dt.datetime.now(pytz.utc)

print(dtime)
print(dtime.tzinfo)

Đầu ra:

2022-12-01 02:07:41.960920+00:00
UTC

Bây giờ không còn là 11 giờ sáng nữa mà là 2 giờ sáng, vì chúng tôi đã đặt múi giờ cách đây vài giờ! Cái này thay đổi múi giờ của ngày giờ.

+00:00 là sự khác biệt giữa thời gian được hiển thị và thời gian UTC với tư cách là điểm neo điều phối toàn cầu. Chúng tôi đã đặt thời gian ở UTC, vì vậy phần bù là 00:00. Đây là một đối tượng nhận biết múi giờ.

Tương tự, chúng ta có thể chuyển đổi cách hiểu của cùng một ngày giờ giữa các múi giờ. Hãy chuyển đổi một chuỗi, chẳng hạn như “2022-06-29 17:08:00” thành một ngày giờ và sau đó bản địa hóa nó vào múi giờ “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)

Lưu ý: Nội địa hóa biến một ngày giờ chưa biết múi giờ thành một ngày giờ nhận biết múi giờ và coi múi giờ là múi giờ cục bộ. Như vậy, các ngày giờ giữ nguyên, nhưng với múi giờ khác, nó không còn đại diện cho cùng một thời điểm không bị ràng buộc từ các múi giờ.

Chúng tôi nhận được như nhau giá trị ngày giờ, bù đắp bởi -04: 00 so với giờ UTC:

2022-06-29 17:08:00-04:00
America/New_York

17:08 tại Tokyo không phải là cùng thời điểm với 17:08 ở New York. 17:08 ở Tokyo là 3:08 ở New York.

Làm cách nào để tìm tất cả các mã/bí danh múi giờ?

Để tìm tất cả các múi giờ có sẵn, hãy kiểm tra all_timezones trường, là danh sách tất cả các múi giờ có sẵn:

print(f'There are {len(pytz.all_timezones)} timezones in PyTzn')
for time_zone in pytz.all_timezones:
   print(time_zone)

Xem hướng dẫn thực hành, thực tế của chúng tôi để học Git, với các phương pháp hay nhất, các tiêu chuẩn được ngành công nghiệp chấp nhận và bảng lừa đảo đi kèm. Dừng lệnh Googling Git và thực sự học nó!

There are 594 timezones in PyTz

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

Thay đổi múi giờ của Datetime

Chúng tôi có thể chuyển đổi múi giờ của nhận biết múi giờ datetime đối tượng từ vùng này sang vùng khác, thay vì bản địa hóa một múi giờ ngây thơ theo múi giờ thông qua lăng kính của một số múi giờ.

Điều này khác với bản địa hóa, vì bản địa hóa biểu thị một thời điểm khác, nhưng việc chuyển đổi múi giờ của một đối tượng biểu thị cùng một thời điểm, thông qua một lăng kính khác:

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)

Đầu tiên, chúng tôi đã tạo một đối tượng datetime với thời gian hiện tại và đặt nó làm múi giờ “America/New_York”. Sau đó sử dụng astimezone() phương pháp, chúng tôi đã chuyển đổi này datetime đến múi giờ “Châu Âu/London”. Cả hai datetimes sẽ in các giá trị khác nhau, sử dụng phần bù UTC làm liên kết tham chiếu giữa chúng:

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 ngày hôm sau tại Luân Đôn is cùng thời điểm với 21:24 ngày hôm trước ở New York vì London đi trước 5 giờ.

Đúng như dự đoán, ngày giờ khác nhau vì chúng cách nhau khoảng 5 giờ.

Chuyển đổi chuỗi thành ngày giờ bằng thư viện của bên thứ ba

Python's datetime mô-đun có thể chuyển đổi tất cả các loại chuỗi khác nhau thành một datetime mục tiêu. Nhưng vấn đề chính là để làm được điều này, bạn cần tạo chuỗi mã định dạng phù hợp strptime() có thể hiểu được. Việc tạo chuỗi này cần có thời gian và làm cho mã khó đọc hơn.

Thay vào đó, chúng ta có thể sử dụng các thư viện bên thứ ba khác để dễ dàng hơn.

Trong một số trường hợp, các thư viện bên thứ ba này cũng có hỗ trợ tích hợp sẵn tốt hơn để thao tác và so sánh ngày giờ, và một số thư viện thậm chí còn có múi giờ tích hợp sẵn, vì vậy bạn không cần đưa vào gói PyTz bổ sung.

Chúng ta hãy xem xét một vài trong số các thư viện này trong các phần sau.

Chuyển đổi chuỗi thành ngày giờ với dateutil

Sản phẩm mô-đun dateutil là một phần mở rộng cho datetime mô-đun. Một lợi thế là chúng ta không cần chuyển bất kỳ mã phân tích cú pháp nào để phân tích một chuỗi!

Để tự động chuyển đổi một chuỗi thành datetime mà không cần mã thông báo định dạng bằng cách sử dụng Python dateutil:

from dateutil.parser import parse
datetime = parse('2018-06-29 22:21:41')

print(datetime)

T parse chức năng sẽ tự động phân tích cú pháp chuỗi! Bạn không cần phải bao gồm bất kỳ chuỗi định dạng nào. Hãy thử phân tích các loại chuỗi khác nhau bằng cách sử dụng 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')

Đầu ra:

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

Bạn có thể thấy rằng hầu hết mọi loại chuỗi đều có thể được phân tích cú pháp dễ dàng bằng cách sử dụng dateutil mô-đun.

Mặc dù điều này thuận tiện, nhưng hãy nhớ lại từ trước rằng việc phải dự đoán định dạng khiến mã chậm hơn nhiều, vì vậy nếu mã của bạn yêu cầu hiệu suất cao thì đây có thể không phải là cách tiếp cận phù hợp cho ứng dụng của bạn.

Chuyển đổi Chuỗi thành Ngày giờ với Maya

Maya cũng giúp dễ dàng phân tích chuỗi và thay đổi múi giờ. Để dễ dàng chuyển đổi một chuỗi bằng Python's Maya:

import maya

dt = maya.parse('2018-04-29T17:45:25Z').datetime()
print(dt.date())
print(dt.time())
print(dt.tzinfo)

Đầu ra:

2018-04-29
17:45:25
UTC

Để chuyển đổi thời gian sang múi giờ khác:

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)

Đầu ra:

2018-04-29
13:45:25
America/New_York

Bây giờ không phải là dễ sử dụng? Hãy thử maya với cùng một bộ chuỗi chúng tôi đã sử dụng với 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)
    
    
    
    

Đầu ra:

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

Như bạn có thể thấy, tất cả các định dạng ngày đã được phân tích cú pháp thành công!

Nếu chúng tôi không cung cấp thông tin múi giờ thì nó sẽ tự động chuyển đổi nó thành UTC. Vì vậy, điều quan trọng cần lưu ý là chúng ta phải cung cấp to_timezonenaive tham số nếu thời gian không ở UTC.

Chuyển đổi Chuỗi thành Ngày giờ bằng Mũi tên

Mũi tên là một thư viện khác để xử lý ngày giờ trong Python. Và như trước đây với maya, nó cũng tự động tìm ra định dạng ngày giờ. Sau khi được giải thích, nó trả về một Python datetime đối tượng từ arrow vật.

Để dễ dàng chuyển đổi một chuỗi thành datetime bằng Python's arrow:

import arrow

dt = arrow.get('2018-04-29T17:45:25Z')
print(dt.date())
print(dt.time())
print(dt.tzinfo)

Đầu ra:

2018-04-29
17:45:25
tzutc()

Và đây là cách bạn có thể sử dụng arrow để chuyển đổi múi giờ bằng cách sử dụng to() phương pháp:

import arrow

dt = arrow.get('2018-04-29T17:45:25Z').to('America/New_York')
print(dt)
print(dt.date())
print(dt.time())

Đầu ra:

2018-04-29T13:45:25-04:00
2018-04-29
13:45:25

Như bạn có thể thấy chuỗi ngày giờ được chuyển đổi thành vùng “America/New_York”.

Bây giờ, hãy sử dụng lại cùng một bộ chuỗi mà chúng ta đã sử dụng ở trên:

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)
    
    
    
    

Mã này sẽ không thành công đối với các chuỗi ngày giờ đã được nhận xét, chiếm hơn một nửa số ví dụ của chúng tôi. Đầu ra cho các chuỗi khác sẽ là:

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

Để phân tích chính xác các chuỗi ngày-giờ được nhận xét, bạn sẽ cần chuyển chuỗi tương ứng định dạng mã thông báo để cung cấp cho thư viện manh mối về cách phân tích nó.

Kết luận

Trong bài viết này, chúng tôi đã chỉ ra các cách khác nhau để phân tích một chuỗi thành một datetime đối tượng trong Python. Bạn có thể chọn Python mặc định datetime thư viện hoặc bất kỳ thư viện bên thứ ba nào được đề cập trong bài viết này, trong số nhiều thư viện khác.

Vấn đề chính với mặc định datetime gói là chúng ta cần chỉ định mã phân tích theo cách thủ công cho hầu hết các định dạng chuỗi ngày-giờ. Vì vậy, nếu định dạng chuỗi của bạn thay đổi trong tương lai, bạn cũng sẽ phải thay đổi mã của mình. Nhưng nhiều thư viện của bên thứ ba, như những thư viện được đề cập ở đây, tự động xử lý nó.

Một vấn đề nữa mà chúng tôi gặp phải là xử lý các múi giờ. Cách tốt nhất để xử lý chúng là luôn lưu trữ thời gian trong cơ sở dữ liệu của bạn ở định dạng UTC, sau đó chuyển đổi nó thành múi giờ địa phương của người dùng khi cần.

Các thư viện này không chỉ tốt cho việc phân tích chuỗi mà còn có thể được sử dụng cho nhiều loại hoạt động liên quan đến ngày giờ khác nhau. Tôi khuyến khích bạn xem qua các tài liệu để tìm hiểu các chức năng một cách chi tiết.

Dấu thời gian:

Thêm từ xếp chồng lên nhau