Câu 1Kết hợp nào tính "3 ngày từ giờ"?
datetime và time — Làm việc với ngày, giờ, và thời gian trôi qua
Học các module datetime / time / calendar của Python từ căn bản. Phủ số học ngày với date / datetime / timedelta, chuyển chuỗi qua strftime / strptime, và đo thời gian trôi qua với time.perf_counter — đều có thực hành.
Bài này đi qua 3 thư viện chuẩn xử lý ngày, giờ, và thời gian trôi qua — datetime / time / calendar. Bạn sẽ thấy số học ngày với date / datetime / timedelta, chuyển chuỗi hai chiều với strftime / strptime, và đo thời gian trôi qua với time.perf_counter.
date / datetime / timedelta — Tạo ngày và tính khoảng cách
Khi bạn làm việc với ngày trong Python, bạn chọn từ 3 class trong module datetime. date chỉ giữ năm/tháng/ngày, datetime thêm giờ/phút/giây, và timedelta đại diện cho một khoảng thời gian như "3 ngày" hoặc "2 giờ". Thiết kế đối xứng: date + timedelta cho bạn "3 ngày từ giờ", và date - date trả về khoảng cách giữa hai ngày dưới dạng timedelta.
| Class | Lưu gì | Dùng điển hình |
|---|---|---|
| date | năm / tháng / ngày | Sinh nhật, ngày đặt — bất cứ gì chỉ ngày quan trọng |
| datetime | năm / tháng / ngày + giờ / phút / giây | Log, thời gian sửa file — bất cứ gì giờ cũng quan trọng |
| timedelta | ngày / giây / microgiây | "3 ngày từ giờ", "thời gian trôi qua" — khoảng thời gian |
| time | giờ / phút / giây (không có ngày) | Chỉ giờ trong ngày, ví dụ "giờ làm việc 9:00 đến 18:00" |
date2 - date1 trả về một timedelta.from datetime import date, datetime, timedelta
# Tạo một ngày
order_date = date(2024, 3, 15)
print(order_date) # 2024-03-15
# Ba ngày sau
delivery = order_date + timedelta(days=3)
print(delivery) # 2024-03-18
# Khoảng cách giữa hai ngày là một timedelta
elapsed = delivery - order_date
print(elapsed.days) # 3
# Thời gian hiện tại
now = datetime.now()
print(now.year, now.month, now.day)
datetime.now và phụ thuộc môi trường
datetime.now() trả về thời gian hiện tại của máy đang chạy code, nên giá trị thay đổi mỗi lần chạy dù bạn ở runtime Pyodide trình duyệt hay máy thật. Bài tập thực hành dùng date(2024, 3, 15) cố định để giữ tính tái lập — thử now() riêng trong console để xem hành vi của nó.
Tính khoảng cách giữa hai ngày
Trừ một ngày từ ngày khác trả về một đối tượng timedelta. Thuộc tính .days cho bạn chỉ số ngày, nên câu hỏi như "còn bao nhiêu ngày đến X?" có câu trả lời số nguyên gọn gàng.
strftime / strptime — Chuyển giữa ngày và chuỗi
Ngày bên trong file, log, hoặc JSON gần như luôn đến dưới dạng chuỗi. Trong Python, strftime (format time) chuyển datetime → chuỗi, và strptime (parse time) chuyển chuỗi → datetime. Cả hai nhận một format code ánh xạ ký hiệu sang ý nghĩa — %Y là năm 4 chữ số, %m là tháng 2 chữ số, v.v.
f là cho format, p là cho parse. Format code (%Y, %m, %d, v.v.) được chia sẻ giữa hai cái.| Format code | Ý nghĩa | Ví dụ |
|---|---|---|
| %Y | Năm 4 chữ số | 2024 |
| %m | Tháng 2 chữ số (01-12) | 03 |
| %d | Ngày 2 chữ số (01-31) | 15 |
| %H | Giờ 24h 2 chữ số (00-23) | 14 |
| %M | Phút 2 chữ số (00-59) | 30 |
| %S | Giây 2 chữ số (00-59) | 00 |
| %A | Tên thứ trong tuần (tiếng Anh) | Friday |
| %w | Số thứ trong tuần (0=CN, 6=T7) | 5 |
from datetime import datetime
# string -> datetime
text = "2024-03-15 14:30:00"
dt = datetime.strptime(text, "%Y-%m-%d %H:%M:%S")
print(dt.year, dt.month, dt.day) # 2024 3 15
# datetime -> string
dt2 = datetime(2024, 3, 15, 14, 30)
print(dt2.strftime("%Y/%m/%d")) # 2024/03/15
print(dt2.strftime("%Y-%m-%d %H:%M")) # 2024-03-15 14:30
Format không khớp raise ValueError
Nếu dấu phân tách trong chuỗi của bạn không khớp format code — ví dụ strptime("2024/03/15", "%Y-%m-%d") — bạn nhận ValueError. Nhìn format thực tế của input và canh dấu gạch ngang với gạch ngang, slash với slash. Cho chuỗi kiểu ISO như "2024-03-15T14:30:00" trộn dấu gạch với T và colon, datetime.fromisoformat(text) dễ hơn.
time và calendar — Đo thời gian trôi qua và kiểm tra tháng
Module time tách biệt khỏi datetime và expose API thời gian cấp thấp hơn. Cái bạn sẽ với tới nhiều nhất là time.perf_counter(), một counter độ phân giải cao trả về thời gian trôi qua hiện tại theo giây (dạng float). Gọi nó hai lần — trước và sau — và hiệu là thời gian thực thi của bạn. Module calendar lấy thông tin lịch như một tháng có bao nhiêu ngày hoặc thứ trong tuần của ngày 1 tháng.
| Hàm | Trả về | Trường hợp dùng |
|---|---|---|
| time.time() | Unix timestamp (float) | Timestamp thời gian hiện tại |
| time.perf_counter() | counter monotonic (float, giây) | Đo thời gian thực thi |
| calendar.monthrange(y, m) | Tuple (thứ của ngày 1, ngày cuối) | Thông tin lịch tháng |
| calendar.isleap(y) | True / False | Kiểm tra năm nhuận |
import time
import calendar
# Đo thời gian thực thi
start = time.perf_counter()
total = sum(range(100000))
elapsed = time.perf_counter() - start
print("Total:", total)
print("Type:", type(elapsed).__name__) # float
# Thông tin lịch
weekday, last_day = calendar.monthrange(2024, 2) # (thứ của ngày 1, ngày cuối)
print("Last day of Feb 2024:", last_day)
print("Leap year:", calendar.isleap(2024))
Vì sao dùng perf_counter thay vì time.time
time.time() trả về Unix timestamp (giây với phần lẻ), nhưng nếu đồng hồ máy bị NTP điều chỉnh lùi, hiệu có thể âm. time.perf_counter() đảm bảo monotonic (luôn tăng) và được thiết kế riêng cho đo thời gian trôi qua, nên cho timing kiểu stopwatch nó là lựa chọn đúng mỗi lần.
time.sleep — Tạm dừng cho khoảng thời gian định
`time.sleep(seconds)` là hàm tạm dừng thực thi cho số giây đã cho. Nó xuất hiện ở khắp nơi — khoảng thời gian retry, rate limiting, timing animation. Tham số là float, nên bạn có thể truyền phân số như time.sleep(0.5). Vì những bài tập này chạy trên trình duyệt, giữ sleep ngắn (0–1 giây) để xác minh hành vi.
Kiểm tra kiến thức
Hãy trả lời từng câu hỏi một.
Câu 2Chuỗi format nào chuyển chuỗi "2024/03/15" thành datetime?
Câu 3Cái nào tốt nhất để đo thời gian thực thi?
Câu 4Cách đơn giản nhất để chuyển chuỗi ISO 8601 "2024-03-15T14:30:00" thành datetime là gì?