核心概念
-
时间戳:
(图片来源网络,侵删)- 定义: 一个浮点数,表示从 1970年1月1日 00:00:00 UTC(协调世界时)到某个时间点所经过的秒数。
- 特点: 它是一个单一的数字,不依赖于任何时区,是全球统一的,非常适合在计算机之间存储和传输时间信息,例如在数据库、日志文件或 API 响应中。
- 注意: Python 的
time模块处理的就是这种时间戳。
-
datetime对象:- 定义: Python 的
datetime模块提供的一个类,用于表示一个具体的日期和时间(年、月、日、时、分、秒、微秒)。 - 特点: 它是一个更“人性化”的时间表示方式,可以方便地进行日期计算、格式化输出等。
- 时区问题:
datetime对象本身可以是“时区无关”(naive)的,也可以是“有时区”(aware)的。强烈推荐使用有时区的对象,以避免因时区差异导致的 bug。
- 定义: Python 的
主要模块
我们将主要使用两个 Python 标准库模块:
datetime: 用于创建和处理datetime对象。time: 主要用于获取当前时间戳。
获取当前时间戳和 datetime 对象
获取当前时间戳
使用 time.time() 函数非常简单。
import time
# 获取当前时间戳(UTC时间)
current_timestamp = time.time()
print(f"当前时间戳: {current_timestamp}")
# 输出示例: 当前时间戳: 1678886400.123456
获取当前 datetime 对象
使用 datetime.datetime.now()。

import datetime
# 获取当前的本地时间(时区无关的 naive datetime)
now_naive = datetime.datetime.now()
print(f"当前本地时间 (naive): {now_naive}")
# 输出示例: 当前本地时间 (naive): 2025-03-15 14:30:00.123456
# 获取当前的 UTC 时间(时区无关的 naive datetime)
now_utc_naive = datetime.datetime.utcnow()
print(f"当前UTC时间 (naive): {now_utc_naive}")
# 输出示例: 当前UTC时间 (naive): 2025-03-15 06:30:00.123456
重要: now() 和 utcnow() 返回的都是“时区无关”的对象,在 Python 3.6+ 中,推荐使用 datetime.now(timezone.utc) 来获取有时区的 UTC 时间。
from datetime import timezone, datetime
# 推荐方式:获取有时区的当前UTC时间
now_aware_utc = datetime.now(timezone.utc)
print(f"当前UTC时间 (aware): {now_aware_utc}")
# 输出示例: 当前UTC时间 (aware): 2025-03-15 06:30:00.123456+00:00
时间戳 与 datetime 对象的相互转换
这是最核心的操作,转换的关键在于理解时间戳是基于 UTC 的。
datetime 对象 -> 时间戳
使用 timestamp() 方法。
import datetime
# 创建一个时区无关的 datetime 对象 (假设是本地时间)
dt_naive = datetime.datetime(2025, 3, 15, 12, 0, 0)
print(f"时区无关的 datetime 对象: {dt_naive}")
# 将其转换为时间戳
# 注意:datetime 对象是时区无关的,Python 会假定它是本地时区
# 这在不同机器上(不同时区)会导致结果不一致,可能出错!
timestamp_from_naive = dt_naive.timestamp()
print(f"从时区无关对象转换的时间戳: {timestamp_from_naive}")
# 正确做法:创建一个有时区的 datetime 对象
# 创建一个 UTC 时间的 datetime 对象
dt_aware_utc = datetime.datetime(2025, 3, 15, 12, 0, 0, tzinfo=datetime.timezone.utc)
print(f"有时区的 UTC datetime 对象: {dt_aware_utc}")
# 将其转换为时间戳 (结果正确且一致)
timestamp_from_aware = dt_aware_utc.timestamp()
print(f"从有时区对象转换的时间戳: {timestamp_from_aware}")
时间戳 -> datetime 对象
使用 datetime.fromtimestamp()。

import datetime
import time
# 假设我们有一个时间戳
my_timestamp = 1678886400.0
# 将时间戳转换为本地时间的 datetime 对象 (时区无关)
dt_local = datetime.datetime.fromtimestamp(my_timestamp)
print(f"时间戳转本地时间 (naive): {dt_local}")
# 输出示例: 2025-03-15 14:30:00 (如果系统时区是 UTC+2)
# 将时间戳转换为 UTC 时间的 datetime 对象 (时区无关)
dt_utc_naive = datetime.datetime.utcfromtimestamp(my_timestamp)
print(f"时间戳转UTC时间 (naive): {dt_utc_naive}")
# 输出示例: 2025-03-15 12:30:00
# 推荐做法:将时间戳转换为有时区的 UTC datetime 对象
# 使用 fromtimestamp 并指定时区为 UTC
dt_aware_utc_from_ts = datetime.datetime.fromtimestamp(my_timestamp, tz=datetime.timezone.utc)
print(f"时间戳转有时区的UTC时间: {dt_aware_utc_from_ts}")
# 输出示例: 2025-03-15 12:30:00+00:00
处理时区(非常重要!)
处理时区是避免时间混乱的关键,Python 3.2+ 引入了 zoneinfo 模块(Python 3.9+ 内置,旧版需安装 tzdata)。
创建有时区的 datetime 对象
from datetime import datetime, timezone, timedelta
import zoneinfo
# 方法1: 使用 UTC
dt_utc = datetime.now(timezone.utc)
print(f"UTC时间: {dt_utc}")
# 方法2: 使用指定时区 ('Asia/Shanghai')
# 确保你的系统安装了 tzdata (Python < 3.9 可能需要手动安装)
try:
shanghai_tz = zoneinfo.ZoneInfo("Asia/Shanghai")
dt_shanghai = datetime.now(shanghai_tz)
print(f"上海时间: {dt_shanghai}")
# 也可以从一个时间戳创建有时区的对象
timestamp = time.time()
dt_shanghai_from_ts = datetime.fromtimestamp(timestamp, tz=shanghai_tz)
print(f"从时间戳创建的上海时间: {dt_shanghai_from_ts}")
except zoneinfo.ZoneInfoNotFoundError:
print("错误: 时区数据库未找到,请确保安装了 tzdata 库。")
# 方法3: 使用固定时区偏移
# UTC+8
tz_eastern = timezone(timedelta(hours=8))
dt_eastern = datetime.now(tz_eastern)
print(f"UTC+8时间: {dt_eastern}")
时区转换
from datetime import datetime
import zoneinfo
# 创建一个上海时间
shanghai_tz = zoneinfo.ZoneInfo("Asia/Shanghai")
dt_shanghai = datetime(2025, 3, 15, 12, 0, 0, tzinfo=shanghai_tz)
print(f"原始上海时间: {dt_shanghai}")
# 将其转换为 UTC 时间
dt_utc_converted = dt_shanghai.astimezone(timezone.utc)
print(f"转换后的UTC时间: {dt_utc_converted}")
# 再将其转换为纽约时间
new_york_tz = zoneinfo.ZoneInfo("America/New_York")
dt_ny_converted = dt_shanghai.astimezone(new_york_tz)
print(f"转换后的纽约时间: {dt_ny_converted}")
datetime 对象的常用操作
格式化输出
使用 strftime() (string format time) 方法。
import datetime
now = datetime.datetime.now()
# 格式化为 YYYY-MM-DD HH:MM:SS
formatted_str1 = now.strftime("%Y-%m-%d %H:%M:%S")
print(f"格式化1: {formatted_str1}")
# 格式化为 YYYY/MM/DD
formatted_str2 = now.strftime("%Y/%m/%d")
print(f"格式化2: {formatted_str2}")
# 格式化为更可读的形式
formatted_str3 = now.strftime("%B %d, %Y, %I:%M %p")
print(f"格式化3: {formatted_str3}")
解析字符串为 datetime 对象
使用 strptime() (string parse time) 方法。
import datetime
date_string = "2025-10-27 15:45:30"
# 将字符串解析为时区无关的 datetime 对象
dt_object = datetime.datetime.strptime(date_string, "%Y-%m-%d %H:%M:%S")
print(f"解析后的datetime对象: {dt_object}")
print(f"对象类型: {type(dt_object)}")
日期计算
datetime 对象支持加减 timedelta 对象来进行时间计算。
import datetime
today = datetime.datetime.now()
# 创建一个时间增量(3天4小时30分钟)
delta = datetime.timedelta(days=3, hours=4, minutes=30)
# 计算未来和过去
future_date = today + delta
past_date = today - delta
print(f" {today}")
print(f"未来3天4小时30分钟后: {future_date}")
print(f"过去3天4小时30分钟前: {past_date}")
总结与最佳实践
- 统一使用 UTC: 在服务器、数据库和 API 之间传输时间时,始终使用 UTC 时间戳,这是避免时区问题的黄金法则。
- 处理时区: 在程序内部处理和显示时间时,尽量使用 有时区的
datetime对象,只在最后一步(显示给用户时)才转换为本地时区。 - 转换要小心:
datetime->timestamp: 确保datetime对象是有时区的,最好是 UTC。timestamp->datetime: 优先使用datetime.fromtimestamp(ts, tz=timezone.utc)来创建 UTC 时间的对象。
- 格式化和解析:
strftime(格式化输出) 和strptime(解析字符串) 的区别。 - 日期计算: 使用
timedelta进行加减法操作。
遵循这些原则,你就能在 Python 中游刃有余地处理各种时间相关的任务。
