杰瑞科技汇

Python时间戳与datetime如何转换?

核心概念

  1. 时间戳:

    Python时间戳与datetime如何转换?-图1
    (图片来源网络,侵删)
    • 定义: 一个浮点数,表示从 1970年1月1日 00:00:00 UTC(协调世界时)到某个时间点所经过的秒数。
    • 特点: 它是一个单一的数字,不依赖于任何时区,是全球统一的,非常适合在计算机之间存储和传输时间信息,例如在数据库、日志文件或 API 响应中。
    • 注意: Python 的 time 模块处理的就是这种时间戳。
  2. datetime 对象:

    • 定义: Python 的 datetime 模块提供的一个类,用于表示一个具体的日期和时间(年、月、日、时、分、秒、微秒)。
    • 特点: 它是一个更“人性化”的时间表示方式,可以方便地进行日期计算、格式化输出等。
    • 时区问题: datetime 对象本身可以是“时区无关”(naive)的,也可以是“有时区”(aware)的。强烈推荐使用有时区的对象,以避免因时区差异导致的 bug。

主要模块

我们将主要使用两个 Python 标准库模块:

  • datetime: 用于创建和处理 datetime 对象。
  • time: 主要用于获取当前时间戳。

获取当前时间戳和 datetime 对象

获取当前时间戳

使用 time.time() 函数非常简单。

import time
# 获取当前时间戳(UTC时间)
current_timestamp = time.time()
print(f"当前时间戳: {current_timestamp}")
# 输出示例: 当前时间戳: 1678886400.123456

获取当前 datetime 对象

使用 datetime.datetime.now()

Python时间戳与datetime如何转换?-图2
(图片来源网络,侵删)
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()

Python时间戳与datetime如何转换?-图3
(图片来源网络,侵删)
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}")

总结与最佳实践

  1. 统一使用 UTC: 在服务器、数据库和 API 之间传输时间时,始终使用 UTC 时间戳,这是避免时区问题的黄金法则。
  2. 处理时区: 在程序内部处理和显示时间时,尽量使用 有时区的 datetime 对象,只在最后一步(显示给用户时)才转换为本地时区。
  3. 转换要小心:
    • datetime -> timestamp: 确保 datetime 对象是有时区的,最好是 UTC。
    • timestamp -> datetime: 优先使用 datetime.fromtimestamp(ts, tz=timezone.utc) 来创建 UTC 时间的对象。
  4. 格式化和解析: strftime (格式化输出) 和 strptime (解析字符串) 的区别。
  5. 日期计算: 使用 timedelta 进行加减法操作。

遵循这些原则,你就能在 Python 中游刃有余地处理各种时间相关的任务。

分享:
扫描分享到社交APP
上一篇
下一篇