Giới thiệu class datetime.datetime và datetime.timedelta

Tuan Tran

Vâng, lại là tôi đây, Tuấn Bond (aka Tuan Tran), chắc hẳn để đến được đây, các bạn đã đọc bài viết “Giới thiệu module datetime, class datetime.date và class.time” rồi nhỉ? Nếu chưa đọc, bạn nên đọc nó nhé, sẽ hữu ích cho bạn đấy. Ở bài viết này chúng ta hãy tìm hiểu một cách khái quát 2 classes tiếp theo: datetime và timedelta của module datetime nào ;)

Wow! tôi có thể có class datetime từ class date và class time thật sao?

Thật ra, câu hỏi trên chỉ mang tính hú họa thôi (nếu bạn có cơ hội tìm hiểu sâu hơn về module này bạn sẽ thấy class datetime này nó được kế thừa từ class date mà thôi :D nhưng chúng ta sẽ không bàn về việc đó ở trong bài viết này, đồng ý nhé). Module datetime cung cấp cho chúng ta một class datetime và class này chứa cả ngày, tháng, năm, giờ, phút, giây. Tuyệt vời chưa. Không hẳn đâu, mọi người nên nghe bài “Sóng Gió” đi là vừa, tất cả chỉ mới bắt đầu thôi ;)

Để khởi tạo một đối tượng datetime bạn cũng sẽ phải truyền giá trị cho nó nhé, trong đó, ngày, tháng và năm là bắt buộc, quan trọng lắm đấy. Ngoài ra, bạn còn có thể truyền thêm 1 số tham số nữa như: hour, minute, second, microsecond, tzinfo và fold nữa (các giá trị này là gì thì bạn tự tìm hiểu thêm nhé :D )

>>> from datetime import datetime
>>> datetime_01 = datetime(2019, 9, 2)
>>> datetime_01
datetime.datetime(2019, 9, 2, 0, 0)
>>> datetime_02 = datetime(2019, 9, 2, 22, 19, 45)
>>> datetime_02
datetime.datetime(2019, 9, 2, 22, 19, 45)

Như bạn thấy đấy, nếu như tôi chỉ truyền ngày, tháng và năm thì đối tượng datetime_01 sẽ có giá trị là 2019-09-02 00:00:00

Và cũng như class date, nếu như bạn muốn lấy giá trị thời gian ở thời điểm hiện tại, vâng, bạn sẽ lấy được đấy

>>> from datetime import datetime
>>> datetime_03 = datetime.now()
>>> datetime_03
datetime.datetime(2019, 9, 2, 22, 26, 22, 395127)
>>>
>>> datetime_04 = datetime.utcnow()
>>> datetime_04
datetime.datetime(2019, 9, 2, 15, 26, 32, 448927)

Ở hình trên, tôi sử dụng 2 phương thức (methods) là now()utcnow(). Vậy nó khác nhau ở chỗ nào nhỉ? Dĩ nhiên là ở cái tên, và cái tên của nó quyết định tất cả đấy :D Với now() kết quả trả về sẽ là thời gian ở thời điểm hiện tại và múi giờ là múi giờ ở máy của tôi (UTC+7). Nhưng với utcnow(), nó cũng trả về thời gian ở thời điểm hiện tại và múi giờ là UTC. Hơi lằng nhằng đấy nhỉ? “Sóng Gió” bắt nguồn từ đây đấy bạn, nhưng bạn yên tâm, tôi sẽ cùng bạn đi đến hết cuộc hành trình này :D

Từ một đối tượng datetime, bạn có thể lấy ra từng giá trị riêng lẻ ngày, tháng, năm, giờ, phút, giây như class time và class date

>>> from datetime import datetime
>>> datetime_05 = datetime.now()
>>> datetime_05
datetime.datetime(2019, 9, 2, 22, 39, 54, 208360)
>>>
>>> datetime_05.year
2019
>>> datetime_05.month
9
>>> datetime_05.day
2
>>> datetime_05.hour
22
>>> datetime_05.minute
39
>>> datetime_05.second
54

Tôi tiếp tục lấy ví dụ trên nhé, từ đối tượng datetime_05 ở hình trên, tôi “biến hóa” nó để cho ra 2 đối tượng datetime đấy. Bạn không tin ư? Hãy nhìn đây :D

>>> date_05 = datetime_05.date()
>>> date_05
datetime.date(2019, 9, 2)
>>>
>>> time_05 = datetime_05.time()
>>> time_05
datetime.time(22, 39, 54, 208360)

Bạn không nhìn nhầm đâu, 2 phương thức date()time() sẽ thực sự trả về đối tượng datetime đấy.

Cũng như class date, class datetime cũng có một số phương thức như sau: replace(), weekday(), isoweekday(), isocalendar()

>>> from datetime import datetime
>>> datetime_06 = datetime.now()
>>> datetime_06
datetime.datetime(2019, 9, 2, 22, 52, 41, 894725)
>>> datetime_06.weekday()
0
>>> datetime_06.isoweekday()
1
>>> datetime_06.isocalendar()
(2019, 36, 1)
>>> datetime_06.replace(year=2020)
datetime.datetime(2020, 9, 2, 22, 52, 41, 894725)

Tôi nghĩ, chỉ cần nhiêu đây là bạn có thể nắm được class datetime nó có những gì rồi, nhưng tôi sẽ dành hẳn 3 bài viết cho 3 phần quan trọng nhất (và trong đó có cả phần múi giờ đấy :D ). Hoặc nếu bạn muốn thách thức khả năng tìm hiểu của bản thân thì có thể xem thêm ở link [1] phần tài liệu tham khảo nhé.

Nào nào, class cuối cùng nào!

Đây sẽ là một class trừu tượng đấy, nếu như bạn bắt đầu làm việc vào vào ngày 2019-09-03 09:00:00 và nghỉ trưa vào lúc 2019-09-03 12:30:00, vậy thời gian bạn làm việc sẽ là 3 giờ 30 phút đúng không nào? Vâng chính cái số 3 giờ 30 phút đó đấy nó sẽ là chủ thể chính ở phần này. 3 giờ 30 phút phút chính là KHOẢNG THỜI GIAN và nó cũng chính là đối tượng của class timedelta. Khi bạn trừ 2 đối tượng datetime (hoặc date) thì kết quả sẽ là một đối tượng timedelta :D

>>> from datetime import datetime, timedelta
>>> datetime_07 = datetime(2019, 1, 2)
>>> datetime_08 = datetime(2019, 2, 3)
>>> datetime_08 - datetime_07
datetime.timedelta(32)

Class timedelta có các tham số sau bạn nhé: days, seconds, microseconds, milliseconds, minutes, hours và weeks. Tất cả các tham số để khởi tạo đối tượng timedelta đều không bắt buộc bạn nhé và mặc định giá trị là một số 0 tròn trĩnh.

Một lưu ý nữa là, class này chỉ lưu trữ days, seconds và microseconds thôi bạn nhé, nên bạn đừng ngạc nhiên với các ví dụ ở dưới tại sao nó lại ra nhiều chữ số đến vậy mặc dù giá trị nhập vào chỉ là vài giờ ;)

Vậy chúng ta nên sử dụng class timedelta như thế nào nhỉ? Trong những trường hơp thực tế, khi bạn bạn có một thời gian ở một thời điểm nào đó và cần tăng thời gian đó lên 2 ngày chẳng hạn, bạn nên sử dụng class timedelta để làm việc đó (hoặc sử dụng function replace() ở trên chẳng hạn, nhưng bạn sẽ cực khổ hơn khi xử lý đấy :D )

>>> from datetime import datetime, timedelta
>>> datetime_09 = datetime(2019, 9, 2)
>>> timedelta_01 = timedelta(days=2)
>>> datetime_00 + timedelta_01
datetime.datetime(2019, 9, 4, 0, 0)

Và, bạn có thể sử dụng một số toán tử nữa, xem ví dụ sau nhé

>>> from datetime import datetime, timedelta
>>> timedelta_02 = timedelta(days=10)
>>> timedelta_03 = timedelta(hours=6)
>>>
>>> timedelta_02 + timedelta_03
datetime.timedelta(10, 21600)
>>>
>>> timedelta_02 - timedelta_03
datetime.timedelta(9, 64800)
>>>
>>> timedelta_02 * 2
datetime.timedelta(20)

Tôi cũng sẽ cho bạn thêm 1 phương thức của class này đó chính là total_seconds(), nó chỉ đơn giản là chuyển hết các số ngày, số giờ… sang số giây mà thôi.

>>> timedelta_02datetime.timedelta(10)
>>> timedelta_02.total_seconds()
864000.0

Nếu bạn tò mò về class này có thể xem thêm ở link [2] ở tài liệu tham khảo nhé.

Tổng kết

Bạn cảm thấy phức tạp phải không? Đừng vội nản, thật lòng mà nói, trong Python 3, module datetime đã hỗ trợ rất tốt việc ánh xạ những gì có ở đời thực (chỉ riêng phần mô tả thời gian thôi bạn nhé :D ) vào trong code bằng các khái niệm mà chúng ta vừa từng bước tiếp cận rồi đấy. 

Nhớ đón đọc bài viết sau nhé, sẽ ngắn gọn hơn bài viết đầu tiên & bài viết này vì nó chỉ tập trung đúng vào 2 phương thức mà thôi, nhưng rất quan trọng đấy ;)

À mà, nếu có thắc mắc, bạn hãy nhớ tạo một câu hỏi ở mục Forum nhé, tôi và các đồng nghiệp của tôi rất thích những câu hỏi của bạn đấy ;)

Tài liệu tham khảo

[1] - https://docs.python.org/3/library/datetime.html#datetime.datetime

[2] - https://docs.python.org/3/library/datetime.html#datetime.timedelta