—— 时间是最好的程序员
from datetime import datetime, date, time, timedelta, timezone
# datetime - 日期+时间
now = datetime.now()
print(now) # 2026-05-19 03:56:00.123456
print(now.year) # 2026
print(now.month) # 5
print(now.day) # 19
print(now.hour) # 3
print(now.weekday()) # 0=周一, 6=周日
print(now.isoweekday()) # 1=周一, 7=周日
# date - 仅日期
today = date.today()
print(today) # 2026-05-19
# time - 仅时间
t = time(14, 30, 0)
print(t) # 14:30:00
# 构造指定日期时间
dt = datetime(2026, 1, 1, 0, 0, 0)
print(dt) # 2026-01-01 00:00:00
from datetime import datetime
# datetime → 字符串
now = datetime.now()
print(now.strftime("%Y-%m-%d")) # 2026-05-19
print(now.strftime("%Y年%m月%d日 %H:%M")) # 2026年05月19日 03:56
print(now.strftime("%A, %B %d, %Y")) # Monday, May 19, 2026
print(now.isoformat()) # 2026-05-19T03:56:00.123456
# 字符串 → datetime
dt1 = datetime.strptime("2026-01-15", "%Y-%m-%d")
dt2 = datetime.strptime("15/01/26 14:30", "%d/%m/%y %H:%M")
# 常用格式符
# %Y 四位年 %m 月 %d 日 %H 24时 %M 分 %S 秒
# %y 两位年 %b 月名缩写 %B 月名全称 %A 星期全称
# %I 12时制 %p AM/PM %f 微秒 %z 时区
# f-string 直接格式化 datetime
now = datetime.now()
print(f"{now:%Y-%m-%d %H:%M:%S}") # 更简洁!
from datetime import datetime, timedelta
now = datetime.now()
# 时间加减
tomorrow = now + timedelta(days=1)
yesterday = now - timedelta(days=1)
next_week = now + timedelta(weeks=1)
two_hours_later = now + timedelta(hours=2)
# 计算两个日期差
birthday = datetime(2026, 12, 25)
diff = birthday - now
print(f"距离生日还有 {diff.days} 天")
# timedelta 属性
delta = timedelta(days=5, hours=3, minutes=30)
print(delta.days) # 5
print(delta.seconds) # 12600 (3h30m = 12600s)
print(delta.total_seconds()) # 469800.0
# 实用:计算某个日期后的第N个工作日
def add_business_days(start_date, days):
current = start_date
added = 0
while added < days:
current += timedelta(days=1)
if current.weekday() < 5: # 0-4 = 周一至周五
added += 1
return current
from datetime import datetime, timezone, timedelta
# 创建时区
UTC = timezone.utc
CST = timezone(timedelta(hours=8)) # 中国标准时间 UTC+8
EST = timezone(timedelta(hours=-5)) # 美东时间 UTC-5
JST = timezone(timedelta(hours=9)) # 日本时间 UTC+9
# 获取带时区的当前时间
utc_now = datetime.now(UTC)
cst_now = datetime.now(CST)
# 时区转换
# 方法1: astimezone()
utc_time = datetime.now(UTC)
beijing = utc_time.astimezone(CST)
tokyo = utc_time.astimezone(JST)
new_york = utc_time.astimezone(EST)
print(f"UTC: {utc_time:%Y-%m-%d %H:%M}")
print(f"北京: {beijing:%Y-%m-%d %H:%M}")
print(f"东京: {tokyo:%Y-%m-%d %H:%M}")
print(f"纽约: {new_york:%Y-%m-%d %H:%M}")
# 方法2: replace() 为无时区时间加时区
naive = datetime(2026, 1, 1, 12, 0) # 无时区信息
aware = naive.replace(tzinfo=CST) # 标记为北京时间
# 使用 zoneinfo(Python 3.9+ 标准库)
from zoneinfo import ZoneInfo
shanghai = ZoneInfo("Asia/Shanghai")
tokyo_tz = ZoneInfo("Asia/Tokyo")
ny_tz = ZoneInfo("America/New_York")
# 自动处理夏令时!
summer_time = datetime(2026, 7, 1, 12, 0, tzinfo=ny_tz)
from datetime import datetime, timedelta, date
def count_business_days(start: date, end: date) -> int:
"""计算两个日期之间的工作日数(不含节假日)"""
if start > end:
start, end = end, start
days = 0
current = start
while current <= end:
if current.weekday() < 5: # 周一~周五
days += 1
current += timedelta(days=1)
return days
def add_business_days(start: date, n: int) -> date:
"""从 start 起第 n 个工作日的日期"""
current = start
added = 0
while added < n:
current += timedelta(days=1)
if current.weekday() < 5:
added += 1
return current
def next_weekday(d: date, weekday: int) -> date:
"""下一个指定的星期几(0=周一, 6=周日)"""
days_ahead = weekday - d.weekday()
if days_ahead <= 0:
days_ahead += 7
return d + timedelta(days=days_ahead)
# 中国法定节假日(示例)
HOLIDAYS_2026 = {
date(2026, 1, 1), # 元旦
date(2026, 2, 17), # 春节
date(2026, 4, 5), # 清明
date(2026, 5, 1), # 劳动节
date(2026, 10, 1), # 国庆
}
def is_workday(d: date) -> bool:
"""判断是否为工作日(排除周末和节假日)"""
if d.weekday() >= 5:
return False
if d in HOLIDAYS_2026:
return False
return True
def deadline_from(start: date, business_days: int) -> date:
"""从 start 起,N个工作日后的截止日期"""
current = start
count = 0
while count < business_days:
current += timedelta(days=1)
if is_workday(current):
count += 1
return current
from datetime import datetime, timezone
# datetime → 时间戳
now = datetime.now(timezone.utc)
ts = now.timestamp()
print(f"时间戳: {ts}") # 1776678960.123456
# 时间戳 → datetime
dt = datetime.fromtimestamp(ts, tz=timezone.utc)
print(dt)
# ISO 8601 格式(推荐用于API)
iso_str = now.isoformat()
print(iso_str) # 2026-05-19T03:56:00.123456+00:00
# 解析 ISO 格式
parsed = datetime.fromisoformat(iso_str)
print(parsed)
# Unix 时间戳转人类可读
def format_timestamp(ts, fmt="%Y-%m-%d %H:%M:%S"):
return datetime.fromtimestamp(ts).strftime(fmt)
#!/usr/bin/env python3
"""第07课 日期时间验证"""
from datetime import datetime, date, timedelta, timezone
def test_datetime_basics():
"""基本操作测试"""
now = datetime.now()
assert isinstance(now.year, int) and now.year >= 2026
dt = datetime(2026, 6, 15, 10, 30)
assert dt.month == 6 and dt.hour == 10
print("✅ 基本操作测试通过")
def test_format_parse():
"""格式化与解析测试"""
dt = datetime(2026, 5, 19, 14, 30, 0)
s = dt.strftime("%Y-%m-%d %H:%M")
assert s == "2026-05-19 14:30"
parsed = datetime.strptime(s, "%Y-%m-%d %H:%M")
assert parsed == dt
print("✅ 格式化与解析测试通过")
def test_timedelta():
"""时间差测试"""
d1 = date(2026, 5, 1)
d2 = date(2026, 5, 10)
diff = d2 - d1
assert diff.days == 9
delta = timedelta(days=5, hours=3)
assert delta.total_seconds() == 5 * 86400 + 3 * 3600
print("✅ 时间差测试通过")
def test_timezone():
"""时区转换测试"""
UTC = timezone.utc
CST = timezone(timedelta(hours=8))
utc_time = datetime(2026, 1, 1, 0, 0, tzinfo=UTC)
beijing = utc_time.astimezone(CST)
assert beijing.hour == 8
print("✅ 时区转换测试通过")
def test_business_days():
"""工作日计算测试"""
def count_biz(start, end):
days = 0
current = start
while current <= end:
if current.weekday() < 5:
days += 1
current += timedelta(days=1)
return days
# 2026-05-18(周一) 到 2026-05-22(周五) = 5个工作日
assert count_biz(date(2026, 5, 18), date(2026, 5, 22)) == 5
# 周六到周一 = 1个工作日
assert count_biz(date(2026, 5, 16), date(2026, 5, 18)) == 1
print("✅ 工作日计算测试通过")
def test_timestamp():
"""时间戳测试"""
dt = datetime(2026, 1, 1, tzinfo=timezone.utc)
ts = dt.timestamp()
dt2 = datetime.fromtimestamp(ts, tz=timezone.utc)
assert dt == dt2
print("✅ 时间戳测试通过")
if __name__ == "__main__":
test_datetime_basics()
test_format_parse()
test_timedelta()
test_timezone()
test_business_days()
test_timestamp()
print("\n🎉 第07课全部验证通过!")
f"{now:%Y-%m-%d}" 比 strftime 更优雅