Python datetime module practical introduction and pitfall avoidance guide

Whether it is doing crawler storage and crawling records, Web backend processing order deadlines or user birthdays, or time series processing in data analysis, Python'sdatetimeThey are all standard library artifacts that cannot be avoided - no needpip install, ready to use right out of the box. This tutorial will help you quickly master its core functions and point out several common pitfalls for novices.

Core modules and classes sorting out

Let me first point out the most confusing detail for a novice: the module name isdatetime, there happens to be another class with the same name nested inside the moduledatetime. In order to make the code clearer, the following examples will accurately import the required classes to avoid confusion.

Get the current date and time

The most basic operation is to obtain the current time (local environment and time zone related content will be introduced later).

# 精准导入 datetime 类(而非整个模块)
from datetime import datetime

# 获取当前本地日期与时间(精确到微秒,不带时区信息)
now_local = datetime.now()
print(now_local)  # 示例输出:2023-07-15 14:30:45.123456
print(type(now_local))  # <class 'datetime.datetime'>

Customize creation date and time

Sometimes we don't need to take "now", but need to specify a specific year, month, day, or even accurate to hours, minutes, seconds, and microseconds.

from datetime import datetime

# 必传参数:年、月、日
dt_basic = datetime(2023, 7, 15)
print(dt_basic)  # 2023-07-15 00:00:00

# 可选参数(按顺序):时、分、秒、微秒
dt_full = datetime(2023, 7, 15, 14, 30, 59, 987654)
print(dt_full)  # 2023-07-15 14:30:59.987654

Bidirectional conversion with timestamp

What is a timestamp?

The timestamp refers to the number of seconds calculated from January 1, 1970 00:00:00 UTC+0 (Greenwich Mean Time). What is returned in Python is a floating point number with microseconds. Its biggest advantage is that it is time zone independent - whether you are in Tokyo or New York, the timestamp of the same moment is exactly the same, so it is very suitable for persistent storage.

datetime to timestamp

from datetime import datetime

dt = datetime(2023, 7, 15, 14, 30)
ts = dt.timestamp()
print(ts)  # 示例输出:1689409800.0

Tips for avoiding pitfalls: local time zone impact

If createddttime zone is not explicitly set,timestamp()Automatically converts to UTC seconds using the local time zone of the running code. This may cause problems when running across environments (such as local Windows, server Linux), so be careful.

Convert timestamp to datetime

There are two commonly used methods, the difference is whether the datetime of "local time zone" or "UTC+0 time zone" is returned:

from datetime import datetime

ts = 1689409800.0

# 方法1:转换为本地时区的 datetime(不带时区标记)
dt_local = datetime.fromtimestamp(ts)

# 方法2:转换为 UTC+0 时区的 datetime(不带时区标记)
dt_utc = datetime.utcfromtimestamp(ts)

print(dt_local)  # 本地时区的 2023-07-15 14:30:00
print(dt_utc)    # 若本地是 UTC+8,这里将是 2023-07-15 06:30:00

Bidirectional conversion with string

When we interact with users, files, and databases, what we most often see are human-readable strings instead of datetime objects. In this case, bidirectional conversion is required.

Convert string to datetime (parsing)

usestrptime()Method for parsing, the core point is to strictly match the format character, the format character must exactly match the string, otherwise an error will be reported.

from datetime import datetime

# 解析 ISO 标准格式(最常用)
date_iso = "2023-07-15 14:30:00"
dt_iso = datetime.strptime(date_iso, '%Y-%m-%d %H:%M:%S')
print(dt_iso)  # 2023-07-15 14:30:00

# 解析中文自然格式
date_cn = "2023年7月15日 14:30"
dt_cn = datetime.strptime(date_cn, '%Y年%m月%d日 %H:%M')
print(dt_cn)  # 2023-07-15 14:30:00

Cheat Sheet for Commonly Used Format Characters

Format symbolsMeaningExample
%Y4-digit year2023
%m2-digit month (01-12)07
%d2-digit date (01-31)15
%HHour in 24-hour format (00-23)14
%M2 digit minutes (00-59)30
%S2-digit seconds (00-59)59
%aEnglish week abbreviationSat
%bEnglish month abbreviationJul

Convert datetime to string (formatting)

usestrftime()Method, also using the above format characters, can flexibly customize the output style.

from datetime import datetime

now = datetime.now()

# 输出人性化的英文格式
fmt_en = now.strftime('%a, %b %d %Y %H:%M:%S')
print(fmt_en)  # 示例:Sat, Jul 15 2023 14:30:45

# 输出简洁的日志格式
fmt_log = now.strftime('%Y%m%d_%H%M%S')
print(fmt_log)  # 示例:20230715_143045

Date and time addition and subtraction operations

Want to calculate "deadline in 3 days" or "crawl time 2 hours ago"? Need to use at this timetimedeltakind. it means twodatetimeThe time difference between them supports the addition and subtraction of days, hours, minutes, seconds and microseconds.

from datetime import datetime, timedelta

now = datetime.now()

# 10小时之后
print(now + timedelta(hours=10))

# 1天3小时之前
print(now - timedelta(days=1, hours=3))

# 两个 datetime 相减,得到 timedelta 对象
dt1 = datetime(2023, 7, 15)
dt2 = datetime(2023, 7, 18)
delta = dt2 - dt1
print(delta.days)  # 3

Simple time zone processing

Python 3.2 and above have built-intimezoneclass, coordinationtimedeltaIt can handle basic time zone requirements.

Explicitly set the time zone of datetime

As mentioned in the previous pit avoidance tips, the default createddatetimeThere are no time zone markers. we can usereplace()method, or directly innow()incomingtzinfoparameters to set the time zone.

from datetime import datetime, timezone, timedelta

# 创建 UTC+8(北京/上海/香港)时区对象
tz_utc8 = timezone(timedelta(hours=8))

# 方法1:在 now() 中直接传入时区
now_utc8 = datetime.now(tz_utc8)
print(now_utc8)  # 示例输出:2023-07-15 14:30:45.123456+08:00

# 方法2:使用 replace() 替换时区(⚠️ 注意:不会自动换算时间!)
dt_local = datetime.now()
dt_utc8_replace = dt_local.replace(tzinfo=tz_utc8)

Conversion between time zones

useastimezone()Method to implement time zone conversion, provided that the original datetime object already carries the time zone mark.

from datetime import datetime, timezone, timedelta

# 先获取带 UTC+0 标记的当前时间
now_utc0 = datetime.now(timezone.utc)

# 转换为东京时间(UTC+9)
tz_utc9 = timezone(timedelta(hours=9))
now_tokyo = now_utc0.astimezone(tz_utc9)
print(now_tokyo)  # 比 now_utc0 多9小时

Best Practice Summary

  1. Prefer to use timestamp or UTC datetime with time zone when storing: time zone independent, safe and stable across environments.
  2. Convert to user time zone during display: For example, the web backend reads the time zone preference of the user's browser, converts it, and then returns it to the front end for display.
  3. Format characters must be strictly matched when parsing with strptime: no space or punctuation mark will be missed.

Small exercise: Convert string with time zone to timestamp

Using the knowledge you learned earlier, try writing a small function to convert a date string with time zone information into a timestamp. This uses the built-in Python 3.9+zoneinfomodule, which is more intuitive to handle.

from datetime import datetime
from zoneinfo import ZoneInfo

def to_utc_ts(dt_str: str, tz_str: str) -> float:
    """
    将时区感知的日期字符串转换为 UTC 时间戳。
    
    :param dt_str: 日期时间字符串,格式 'YYYY-MM-DD HH:MM:SS'
    :param tz_str: 时区名,如 'Asia/Shanghai', 'America/New_York'
    :return: UTC 时间戳
    """
    # 1. 解析日期时间字符串
    naive_dt = datetime.strptime(dt_str, '%Y-%m-%d %H:%M:%S')
    # 2. 附加时区信息
    aware_dt = naive_dt.replace(tzinfo=ZoneInfo(tz_str))
    # 3. 转换为时间戳(后台自动计算 UTC 秒数)
    return aware_dt.timestamp()

# 测试一下
if __name__ == '__main__':
    ts_shanghai = to_utc_ts('2023-07-15 14:30:00', 'Asia/Shanghai')
    print(ts_shanghai)  # 1689409800.0

    ts_newyork = to_utc_ts('2023-07-15 02:30:00', 'America/New_York')
    print(ts_newyork)  # 与上面相同,因为代表同一瞬间

By mastering the above core functions, you can easily handle 90% of the date and time processing needs in daily development.