核心概念
-
时间戳:
(图片来源网络,侵删)- 一个浮点数或整数,表示从 1970年1月1日 00:00:00 UTC(协调世界时)到某个特定时间点所经过的秒数。
- 它也被称为 "Unix Timestamp" 或 "Epoch Time"。
- 这个时间点被称为 纪元。
- 时间戳与时区无关,它只是一个绝对的数值。
-
datetime对象:- Python 的
datetime模块提供的类,用于表示一个具体的日期和时间。 datetime对象本身是“天真”的,即它不包含时区信息,或者它可以是“感知”的,即包含时区信息(通过tzinfo属性)。- 在进行时间戳转换时,时区处理至关重要。
- Python 的
关键模块和函数
我们将主要使用 datetime 和 time 模块。
datetime.datetime: 表示日期和时间。datetime.timezone: 用于创建带时区的datetime对象。time.time(): 获取当前时间戳。datetime.datetime.fromtimestamp(): 将时间戳转换为datetime对象。datetime.datetime.timestamp(): 将datetime对象转换为时间戳。
获取当前时间戳
使用 time.time() 是最直接的方法。
import time
# 获取当前时间戳(UTC时间)
current_timestamp = time.time()
print(f"当前时间戳: {current_timestamp}")
# 输出类似: 当前时间戳: 1678886400.123456
将时间戳转换为 datetime 对象
这是最常见的操作,使用 datetime.datetime.fromtimestamp() 方法。

重要:时区问题!
这个方法的行为取决于你的系统设置,并且默认会使用你系统的本地时区,为了确保代码的可移植性和正确性,强烈建议总是明确指定时区。
示例 A:转换为本地时区的 datetime 对象
import datetime
timestamp = 1678886400 # 这是一个示例时间戳
# fromtimestamp 默认会转换为本地时区的 datetime 对象
local_datetime = datetime.datetime.fromtimestamp(timestamp)
print(f"时间戳: {timestamp}")
print(f"本地时区 datetime 对象: {local_datetime}")
print(f"时区信息: {local_datetime.tzinfo}") # 输出 None,表示是“天真”的 datetime 对象
# 输出将根据你所在的时区而变化
# 在中国时区 (UTC+8):
# 时间戳: 1678886400
# 本地时区 datetime 对象: 2025-03-15 08:00:00
# 时区信息: None
示例 B:转换为 UTC 时间的 datetime 对象(推荐)
为了获得一个与系统无关的、标准的结果,最好将时间戳转换为 UTC 时间。
import datetime
timestamp = 1678886400
# 使用 timezone.utc 来指定 UTC 时区
utc_datetime = datetime.datetime.fromtimestamp(timestamp, tz=datetime.timezone.utc)
print(f"时间戳: {timestamp}")
print(f"UTC 时区 datetime 对象: {utc_datetime}")
print(f"时区信息: {utc_datetime.tzinfo}")
# 输出:
# 时间戳: 1678886400
# UTC 时区 datetime 对象: 2025-03-15 00:00:00+00:00
# 时区信息: UTC
注意: +00:00 表示 UTC 时间,也被称为 "Zulu time"。
将 datetime 对象转换为时间戳
使用 datetime 对象的 .timestamp() 方法。

重要:时区问题!
.timestamp() 方法要求 datetime 对象必须是“感知”的(即包含时区信息),如果传入一个“天真”的 datetime 对象,Python 会假设它是你系统的本地时区,这可能会导致意外的结果。
示例 A:从带时区的 datetime 对象转换(推荐)
import datetime
# 创建一个带 UTC 时区的 datetime 对象
# 注意 tzinfo 参数
dt_aware = datetime.datetime(2025, 3, 15, 0, 0, 0, tzinfo=datetime.timezone.utc)
# 将其转换为时间戳
timestamp_from_utc = dt_aware.timestamp()
print(f"UTC datetime 对象: {dt_aware}")
print(f"转换后的时间戳: {timestamp_from_utc}")
# 输出:
# UTC datetime 对象: 2025-03-15 00:00:00+00:00
# 转换后的时间戳: 1678886400.0
示例 B:从本地时区的 datetime 对象转换
如果你有一个“天真”的 datetime 对象,但你知道它代表的是本地时间,可以这样做:
import datetime
# 创建一个“天真”的 datetime 对象(不包含时区信息)
# 假设这个时间代表的是北京时间 (UTC+8)
dt_naive = datetime.datetime(2025, 3, 15, 8, 0, 0)
# 将其视为本地时间,并手动附加时区信息
# 首先创建一个本地时区对象(这里以北京时间为例)
# 注意:Python 3.9+ 可以使用 datetime.timezone(datetime.timedelta(hours=8))
# 更通用的方法是使用 pytz 或 zoneinfo 库,但这里用简单方法
local_tz = datetime.timezone(datetime.timedelta(hours=8))
dt_local = dt_naive.replace(tzinfo=local_tz)
# 现在将其转换为时间戳
timestamp_from_local = dt_local.timestamp()
print(f"本地时区 datetime 对象: {dt_local}")
print(f"转换后的时间戳: {timestamp_from_local}")
# 输出:
# 本地时区 datetime 对象: 2025-03-15 08:00:00+08:00
# 转换后的时间戳: 1678886400.0
可以看到,同一个时间点(2025-03-15 00:00 UTC 和 2025-03-15 08:00 CST)对应的时间戳是相同的。
处理毫秒
时间戳通常是浮点数,小数部分代表毫秒、微秒等。datetime 对象也能完美处理。
import datetime
# 一个包含毫秒的时间戳
timestamp_with_ms = 1678886400.123
# 转换为 datetime 对象
dt_from_ms = datetime.datetime.fromtimestamp(timestamp_with_ms, tz=datetime.timezone.utc)
print(f"带毫秒的时间戳: {timestamp_with_ms}")
print(f"转换后的 datetime 对象: {dt_from_ms}")
# 微秒部分会显示 .123000
# 反向转换
new_timestamp = dt_from_ms.timestamp()
print(f"转换回的时间戳: {new_timestamp}")
总结与最佳实践
- 始终考虑时区:时区是时间处理中最容易出错的地方。
- 内部处理用 UTC:在应用程序内部存储和传递时间时,尽量使用 UTC 时间的
datetime对象,这样可以避免时区转换带来的混乱。 - 对外显示时再转换:只在需要向用户显示时间时,才将 UTC 时间转换成用户所在时区的本地时间。
- 使用“感知”的
datetime对象:在进行时间戳转换时,确保你的datetime对象是带时区信息的(即tzinfo不为None)。 - 优先使用
datetime.timezone:对于简单的时区需求,datetime.timezone足够,对于更复杂的时区规则(如夏令时),建议使用第三方库pytz或 Python 3.9+ 内置的zoneinfo模块。
完整示例
下面是一个综合性的示例,展示了从当前时间戳开始,到转换、再到转换回来的完整流程。
import datetime
import time
# 1. 获取当前时间戳
current_ts = time.time()
print(f"1. 当前时间戳: {current_ts}")
# 2. 将时间戳转换为 UTC 的 datetime 对象(推荐做法)
utc_now = datetime.datetime.fromtimestamp(current_ts, tz=datetime.timezone.utc)
print(f"2. 当前 UTC 时间: {utc_now}")
# 3. 将 UTC 时间转换为本地时间的 datetime 对象(用于显示)
# 方法一:手动指定本地时区偏移(简单但不精确,不考虑夏令时)
# local_offset = datetime.timedelta(hours=8) # 假设是北京时间
# local_now = utc_now.astimezone(timezone(local_offset))
# 方法二:更通用的方法,使用系统本地时区
# 在 Python 3.6+ 中,datetime.now() 可以接受一个时区参数
# 但为了兼容性,我们可以这样:
local_now = utc_now.astimezone() # 自动转换为系统本地时区
print(f"3. 当前本地时间: {local_now}")
# 4. 将本地时间的 datetime 对象转换回时间戳
# local_now 是一个“感知”的对象,所以可以直接转换
ts_back_from_local = local_now.timestamp()
print(f"4. 从本地时间转换回的时间戳: {ts_back_from_local}")
# 5. 验证
print(f"\n验证: {current_ts == ts_back_from_local}") # 应该输出 True 