Chuyển đến nội dung chính

Python datetime: Cách làm việc với ngày và giờ trong Python

Tìm hiểu các cách làm việc với bộ công cụ datetime của Python và đơn giản hóa mọi thứ từ phân tích chuỗi đến quản lý dấu thời gian nhận biết múi giờ.
· 2 phút đọc

Khám phá cùng AI

Làm việc với ngày và giờ có vẻ đơn giản cho đến khi bạn đụng đến định dạng, múi giờ, quy tắc giờ mùa hè hoặc dấu thời gian từ nhiều hệ thống, lúc đó bạn không thể lưu thời gian dưới dạng chuỗi hay số nguyên thô nữa. Mô-đun datetime của Python được tạo ra để giúp bạn quản lý tất cả những phần chuyển động này theo cách có thể dự đoán.

Hướng dẫn này đi qua các lớp cốt lõi, cách tạo và làm việc với đối tượng datetime, cách thực hiện phép toán, cách định dạng và phân tích giá trị, xử lý múi giờ và hơn thế nữa. Mỗi phần xây dựng trên phần trước, giúp bạn chuyển từ thao tác cơ bản sang các mẫu nâng cao.

Các lớp cốt lõi của mô-đun datetime trong Python

Trước khi làm điều gì cụ thể, sẽ hữu ích nếu hiểu Python mô hình hóa ngày và giờ ở mức khái niệm như thế nào. Mô-đun datetime dùng một tập nhỏ các lớp, mỗi lớp tập trung vào một phần của vấn đề. Biết mỗi lớp phù hợp ở đâu sẽ khiến phần còn lại của quy trình làm việc dễ dàng hơn nhiều.

date

Khi bạn chỉ cần một ngày dương lịch mà không bận tâm đến thời điểm trong ngày hay múi giờ, lớp date là thứ bạn cần. Nó biểu diễn năm, tháng và ngày bằng các thuộc tính quen thuộc.

Các thuộc tính bao gồm:

  • year

  • month

  • day

Và các phương thức:

  • today()

  • fromisoformat()

  • replace()

  • isoformat()

  • weekday()

  • isoweekday()

from datetime import date
d = date(2025, 3, 1)
print(d)

Đoạn mã này tạo một ngày dương lịch đơn giản. Nếu bạn nhập một tổ hợp không hợp lệ (như February 30), Python sẽ phát sinh một ValueError.

time

Một số tác vụ chỉ quan tâm đến thời điểm trong ngày, ví dụ một lời nhắc chạy lúc 2:30 PM. Lớp time sẽ hữu ích vì nó lưu trữ giờ, phút, giây và (không cần cho ví dụ này) microsecond hoặc dữ liệu múi giờ.

Các thuộc tính gồm: hour, minute, second, microsecond, tzinfo

Các phương thức gồm: replace(), isoformat()

from datetime import time
t = time(14, 30, 15)
print(t)

Điều này tạo một thời điểm trong ngày không gắn với ngày. Giá trị không hợp lệ (như hour=27) sẽ tạo lỗi.

datetime

Hầu hết các tình huống thực tế kết hợp cả ngày và giờ, đó là lúc datetime xuất hiện. Đây là lớp linh hoạt nhất trong mô-đun và là lớp bạn sẽ dùng thường xuyên nhất cho ghi log, xử lý và điều phối sự kiện.

Các thuộc tính (bên cạnh tất cả các thuộc tính ở trên): tzinfo

Và các phương thức là now(), utcnow(), fromisoformat(), strptime(), strftime(), astimezone(). Nó cũng hỗ trợ phép toán với timedelta, tôi sẽ nói chi tiết hơn.

from datetime import datetime
dt = datetime(2025, 3, 1, 14, 30)
print(dt)

Điều này tạo ra một dấu thời gian đầy đủ với cả thành phần ngày và giờ.

timedelta

Bất cứ khi nào bạn cần đo thời gian trôi qua hoặc dịch chuyển một dấu thời gian tiến hoặc lùi, timedelta là lựa chọn phù hợp. Nó biểu diễn một khoảng thời lượng, không phải một thời điểm cụ thể.

Các thuộc tính gồm: days, seconds, microseconds. Thường dùng cho độ lệch, chênh lệch thời gian và logic lập lịch.

from datetime import timedelta
delta = timedelta(days=7, hours=3)
print(delta)

Điều này biểu diễn một khoảng thời lượng cố định. Nó đặc biệt hữu ích khi cộng hoặc trừ với một datetime.

tzinfo

tzinfo định nghĩa giao diện của Python dành cho múi giờ. Bạn sẽ không tạo những đối tượng này trực tiếp, nhưng hệ thống datetime sử dụng chúng bất cứ khi nào bạn gắn hoặc chuyển đổi múi giờ.

timezone

timezone là một triển khai tzinfo dựng sẵn cho các độ lệch UTC cố định như UTC hoặc UTC+1. Nó hữu ích cho các trường hợp đơn giản nơi quy tắc giờ mùa hè không quan trọng.

Tạo và truy cập đối tượng datetime trong Python

Khi đã biết các lớp, bước tiếp theo là học cách tạo các thể hiện của chúng. Python cung cấp vài cách tùy theo nguồn dữ liệu của bạn: nhập thủ công, thời gian hệ thống, dấu thời gian hoặc văn bản.

Dùng hàm khởi tạo của lớp

Hàm khởi tạo cho bạn toàn quyền kiểm soát các giá trị đang tạo. Đây thường là cách rõ ràng và ít lỗi nhất để xây dựng đối tượng date, time hoặc datetime.

from datetime import date
d = date(2025, 3, 1)
print(d)

Điều này xây dựng trực tiếp một ngày dương lịch. Giá trị không hợp lệ sẽ lập tức phát sinh lỗi, giúp phát hiện sai sót sớm.

from datetime import time
t = time(14, 30, 15)
print(t)

Điều này tạo ra một giá trị thời điểm trong ngày. Dùng khi bạn không cần gắn kèm ngày.

from datetime import datetime
dt = datetime(2025, 3, 1, 14, 30)
print(dt)

Điều này tạo một dấu thời gian đầy đủ. Thêm đối số tzinfo sẽ giúp nó nhận biết múi giờ.

Tạo từ dấu thời gian

Dấu thời gian Unix xuất hiện trong log, API và hệ điều hành. Python chuyển đổi chúng dễ dàng thành đối tượng datetime dễ đọc.

datetime.fromtimestamp(1700000000)
datetime.utcfromtimestamp(1700000000)

Hàm đầu diễn giải dấu thời gian theo giờ địa phương; hàm thứ hai diễn giải theo UTC.

Phương thức lớp cho giá trị hiện tại

Khi bạn cần ngày hoặc giờ hiện tại, Python cung cấp các tiện ích đơn giản. Chúng rất cần thiết cho ghi log, theo dõi sự kiện và pipeline thời gian thực.

from datetime import datetime, date, timezone
print(date.today())
print(datetime.now())
print(datetime.now(tz=timezone.utc))  # Python 3.12+ preferred

Những hàm này trả về thời gian hệ thống hiện tại theo giờ địa phương hoặc UTC, tùy nhu cầu của bạn.

datetime.fromtimestamp(1700000000)
datetime.utcfromtimestamp(1700000000)

Những hàm này chuyển đổi dấu thời gian epoch thành đối tượng datetime. Chúng cực kỳ phổ biến khi phân tích giá trị từ API hoặc cơ sở dữ liệu.

Phân tích từ chuỗi

Tập dữ liệu thực tế thường lưu dấu thời gian dưới dạng văn bản. Python cung cấp công cụ đáng tin cậy để chuyển các chuỗi đó thành giá trị có cấu trúc.

strptime()
from datetime import datetime
dt = datetime.strptime("2025-03-01 14:30", "%Y-%m-%d %H:%M")
print(dt)

strptime() phân tích một chuỗi theo mẫu định dạng. Nếu chuỗi không khớp chính xác, Python sẽ phát sinh ValueError.

from datetime import datetime
dt = datetime.strptime("not-a-date", "%Y-%m-%d")

Điều này sẽ thất bại vì đầu vào không khớp với mẫu mong đợi.

fromisoformat()
datetime.fromisoformat("2025-03-01T14:30:00")

Chuỗi ISO 8601 được phân tích mượt mà vì cấu trúc được tiêu chuẩn hóa. Đây thường là cách dễ nhất để nạp dấu thời gian từ API hoặc pipeline dữ liệu hiện đại.

Thực hiện phép toán với ngày giờ

Khi bạn đã có thể tạo dấu thời gian, bước tiếp theo là làm việc với chúng. Bạn có thể làm điều này bằng cách tính thời lượng, dịch chuyển ngày hoặc so sánh khoảng thời gian.

Timedelta cho các phép tính thời gian

timedelta mô hình hóa các khoảng thời lượng cố định như “5 giờ” hoặc “2 tuần”. Những khoảng này hữu ích cho lập lịch, ghi log và khi bạn cần đếm ngược đơn giản.

from datetime import datetime, timedelta
dt = datetime(2025, 3, 1, 14, 30)
new_dt = dt + timedelta(days=5)
print(new_dt)

Ví dụ này dịch chuyển dấu thời gian tiến 5 ngày.

start = datetime(2025, 3, 1, 9, 0)
end = datetime(2025, 3, 1, 14, 30)
duration = end - start
print(duration.total_seconds())

Ở đây, trừ hai datetime cho bạn một timedelta, có thể chuyển đổi sang giây, ngày hoặc giờ.

Thời lượng cố định so với phép toán nhận biết lịch

Không phải mọi đơn vị thời gian đều như nhau. Số ngày trong tháng thay đổi, năm có thể có ngày nhuận và hành vi cuối tháng có thể khó đoán. Với những kịch bản này, timedelta là chưa đủ.

dateutil.relativedelta xử lý phép toán “nhận biết lịch”:

from dateutil.relativedelta import relativedelta
from datetime import date
d = date(2025, 1, 31)
print(d + relativedelta(months=1))

Điều này xử lý đúng kịch bản thiếu “February 31” bằng cách dịch chuyển ngày một cách phù hợp.

Định dạng và phân tích ngày giờ

Định dạng datetime xuất hiện ở khắp nơi: API kỳ vọng định dạng cụ thể, người dùng thích văn bản dễ đọc và log phụ thuộc vào chuỗi dấu thời gian nhất quán. Python hỗ trợ cả định dạng linh hoạt và biểu diễn tiêu chuẩn.

Định dạng chuỗi với strftime

strftime() cho phép bạn chuyển đối tượng datetime thành chuỗi định dạng bằng các mã định sẵn.

from datetime import datetime
dt = datetime(2025, 3, 1, 14, 30)
print(dt.strftime("%A, %B %d, %Y at %H:%M"))

Điều này in ra một chuỗi dễ đọc với thứ trong tuần và tên tháng đầy đủ.

dt.strftime("%Y-%m-%dT%H:%M:%S")

Điều này tạo ra một chuỗi giống ISO, phù hợp để lưu trữ dữ liệu hoặc dùng cho API.

Phân tích chuỗi với strptime

from datetime import datetime
dt = datetime.strptime("2025-03-01 14:30", "%Y-%m-%d %H:%M")
print(dt)

Điều này chuyển văn bản thành một đối tượng datetime. Bất kỳ sai khớp nào giữa chuỗi và mẫu đều phát sinh lỗi.

Làm việc với ISO 8601 và RFC 3339

ISO 8601 giải quyết sự mơ hồ có trong nhiều định dạng ngày theo vùng. Python hỗ trợ nó sẵn có:

from datetime import datetime
dt = datetime.fromisoformat("2025-03-01T14:30:00")
print(dt.isoformat())

Đây là định dạng an toàn nhất khi trao đổi dữ liệu giữa các hệ thống, API hoặc cơ sở dữ liệu.

Xử lý múi giờ

Múi giờ mang đến một số thách thức khó nhất trong lập trình thời gian. Python hỗ trợ bằng cách phân biệt giữa đối tượng datetime “ngây thơ” và “nhận biết” múi giờ, đồng thời cung cấp công cụ để xử lý múi giờ thực tế.

Đối tượng datetime ngây thơ so với nhận biết múi giờ

Datetime ngây thơ không có múi giờ:

from datetime import datetime
naive_dt = datetime(2025, 3, 1, 14, 30)
print(naive_dt.tzinfo)  # None

Datetime nhận biết bao gồm độ lệch múi giờ:

from datetime import timezone, timedelta
aware_dt = naive_dt.replace(tzinfo=timezone(timedelta(hours=1)))
print(aware_dt)

Trộn lẫn giá trị ngây thơ và nhận biết trong so sánh hoặc phép toán thường gây lỗi.

Sử dụng mô-đun zoneinfo

Mô-đun zoneinfo của Python cung cấp quyền truy cập các múi giờ IANA thực tế:

from zoneinfo import ZoneInfo
from datetime import datetime
dt = datetime(2025, 3, 1, 14, 30, tzinfo=ZoneInfo("Europe/Paris"))
print(dt)

Chuyển đổi múi giờ rất đơn giản:

dt.astimezone(ZoneInfo("America/New_York"))

Điều này biểu diễn đúng thời điểm đó trong một múi giờ địa phương khác.

Chuyển đổi giữa các múi giờ

Bạn có thể chuyển bất kỳ dấu thời gian nhận biết nào sang múi giờ khác bằng astimezone():

from zoneinfo import ZoneInfo
dt_ny = dt.astimezone(ZoneInfo("America/New_York"))
print(dt_ny)

Thực tiễn tốt phổ biến là lưu dấu thời gian theo UTC và chỉ chuyển đổi khi cần hiển thị.

So sánh và lọc ngày giờ

So sánh xuất hiện trong hầu hết mọi quy trình. Tôi đang nghĩ đến việc sắp xếp log, lọc sự kiện hoặc xác định liệu điều gì đó xảy ra trước hay sau một ngưỡng.

from datetime import datetime
a = datetime(2025, 3, 1, 12, 0)
b = datetime(2025, 3, 1, 15, 0)
print(a < b)  # True

So sánh nhận biết múi giờ sẽ tính đến độ lệch:

from datetime import datetime
from zoneinfo import ZoneInfo
dt1 = datetime(2025, 3, 1, 12, 0, tzinfo=ZoneInfo("Europe/London"))
dt2 = datetime(2025, 3, 1, 7, 0, tzinfo=ZoneInfo("America/New_York"))
print(dt1 == dt2)  # True — same moment in time

Lọc tập hợp hoạt động một cách tự nhiên:

dates = [
    datetime(2025, 3, 1, 10),
    datetime(2025, 2, 20, 9),
    datetime(2025, 3, 1, 8)
]
cutoff = datetime(2025, 3, 1)
filtered = [d for d in dates if d >= cutoff]
print(filtered)

Chuẩn hóa về UTC hữu ích khi làm việc xuyên múi giờ.

Các trường hợp sử dụng nâng cao hơn

Datetime xuất hiện trong nhiều quy trình ngoài việc phân tích và phép toán cơ bản. Dưới đây là vài mẫu bạn sẽ thường gặp.

Dấu thời gian Unix

Dấu thời gian Unix đo số giây kể từ ngày 1 tháng 1 năm 1970 (UTC). Chúng được dùng rộng rãi trong lập trình hệ thống và API.

from datetime import datetime
dt = datetime.fromtimestamp(1700000000)
print(dt)

Milli giây và micro giây cần được chia tỷ lệ:

ts_ms = 1700000000000
dt_ms = datetime.fromtimestamp(ts_ms / 1000)

ts_us = 1700000000000000
dt_us = datetime.fromtimestamp(ts_us / 1_000_000)

Lập lịch và bộ hẹn giờ

Các thư viện như schedule phụ thuộc vào giá trị datetime để xác định khi nào nên chạy tác vụ. Dù bạn kích hoạt hàm mỗi vài giây hay lập lịch một sự kiện một lần trong ngày, datetime cung cấp nền tảng cho các phép so sánh đó.

Mẫu phân tích dữ liệu

Các thuộc tính của datetime thường được trích xuất để gom nhóm và phân tích theo thời gian:

dt = datetime(2025, 3, 1, 14, 30)
print(dt.year)
print(dt.isocalendar())

Trong pandas, lấy mẫu lại theo chu kỳ là vô cùng phổ biến:

import pandas as pd
df = pd.DataFrame({
    "value": [10, 12, 15],
    "timestamp": pd.to_datetime([
        "2025-03-01",
        "2025-03-02",
        "2025-03-08"
    ])
}).set_index("timestamp")

print(df.resample("W").sum())

Kết luận

Để tìm hiểu thêm về datetime, vui lòng xem video từ khóa học Working with Dates and Times in Python của Max Shrom và Data Types for Data Science in Python của Jason Myers.

Bạn cũng có thể thấy hữu ích bài hướng dẫn Converting Strings to Dates as datetime Objects nếu cần thêm một chút trợ giúp khi chuyển đổi chuỗi.

Oluseye Jeremiah

Tác giả

Oluseye Jeremiah

Nhà viết nội dung về công nghệ, chuyên về AI, ML và khoa học dữ liệu, giúp làm rõ và phổ biến những ý tưởng phức tạp.

Chủ đề

Liên quan