Python3 中如何格式化时间并处理时区问题

from datetime import datetime
from pytz import timezone

tzc = timezone(‘PRC’) tzu = timezone(‘US/Hawaii’)

time = datetime.utcnow()

print(‘C:’+time.replace(tzinfo=tzc).astimezone(tz=tzc).strftime(’%H’)) print(‘U:’+time.replace(tzinfo=tzu).astimezone(tz=tzu).strftime(’%H’))

为毛两个输出是一样的?


Python3 中如何格式化时间并处理时区问题

16 回复

In [24]: from datetime import datetime
…: from pytz import timezone
…: import pytz
…: tzc = timezone(‘PRC’)
…: tzu = timezone(‘US/Hawaii’)
…:
…: time = datetime.utcnow()
…:
…: print(‘C:’+time.replace(tzinfo=tzc).astimezone(tz=pytz.utc).strftime(’%H’))
…: print(‘U:’+time.replace(tzinfo=tzu).astimezone(tz=pytz.utc).strftime(’%H’))
…:
C:04
U:23


在Python3里处理时间和时区,主要用datetime模块配合pytz或Python 3.9+的zoneinfo。下面给你几个常用场景的代码。

1. 获取当前时间并格式化

from datetime import datetime

# 获取当前本地时间
now_local = datetime.now()
print(f"本地时间: {now_local}")

# 获取当前UTC时间
now_utc = datetime.utcnow()
print(f"UTC时间: {now_utc}")

# 格式化时间
formatted = now_local.strftime("%Y-%m-%d %H:%M:%S")
print(f"格式化后: {formatted}")

2. 处理时区(Python 3.9+推荐用zoneinfo)

from datetime import datetime
from zoneinfo import ZoneInfo

# 创建带时区的时间
tz_shanghai = ZoneInfo("Asia/Shanghai")
tz_ny = ZoneInfo("America/New_York")

# 当前上海时间
now_shanghai = datetime.now(tz_shanghai)
print(f"上海时间: {now_shanghai}")

# 转换时区
now_ny = now_shanghai.astimezone(tz_ny)
print(f"纽约时间: {now_ny}")

3. 处理时区(老版本用pytz)

import pytz
from datetime import datetime

# 创建带时区的时间
tz_shanghai = pytz.timezone("Asia/Shanghai")
tz_ny = pytz.timezone("America/New_York")

now_shanghai = datetime.now(tz_shanghai)
now_ny = now_shanghai.astimezone(tz_ny)

print(f"上海时间: {now_shanghai}")
print(f"纽约时间: {now_ny}")

4. 时间字符串解析(带时区)

from datetime import datetime
from zoneinfo import ZoneInfo

# 解析带时区的时间字符串
time_str = "2024-01-15 14:30:00+08:00"
parsed_time = datetime.fromisoformat(time_str)
print(f"解析结果: {parsed_time}")

# 转换到其他时区
tz_tokyo = ZoneInfo("Asia/Tokyo")
tokyo_time = parsed_time.astimezone(tz_tokyo)
print(f"东京时间: {tokyo_time}")

5. 常用格式化符号

  • %Y: 四位年份(2024)
  • %m: 两位月份(01-12)
  • %d: 两位日期(01-31)
  • %H: 24小时制小时(00-23)
  • %M: 分钟(00-59)
  • %S: 秒(00-59)
  • %z: 时区偏移(+0800)
  • %Z: 时区名称(CST)

关键点总结:

  • Python 3.9+直接用zoneinfo,更标准
  • 老项目用pytz,注意它的localize()方法
  • 存储和传输用UTC,显示时再转本地时区
  • strftime()格式化,strptime()解析

用zoneinfo吧,标准库更省心。

时间的比较应该在同一个时区下. 还有 replace 有坑, 使用 tzc.localize 更好

#2 关键是 python 输出个时间要这么麻烦吗?

#1 py3.5.2 表示两个输出一毛一样

Python 本身的时区支持好像有问题,我之前遇到这个问题是直接用的第三方库,pendulum,https://github.com/sdispater/pendulum。简单,好用,

```
pendulum.now(‘Asia/Shanghai’)

Orz,不知道怎么按到 Enter 了,重新来。

<br>import pendulum<br>t1=pendulum.now('Asia/Shanghai')<br>t2=t1.in_timezone('US/Hawaii')<br># 下面两个的输出绝对不一样<br>t1.strftime("%H")<br>t2.strftime("%H")<br>

因为你理解错了 time.replace 的意思了。 可以这样用

python<br>from datetime import datetime<br>from pytz import timezone<br><br>tzc = timezone('PRC')<br>tzu = timezone('US/Hawaii')<br><br>now = datetime.now(pytz.utc)<br><br>now.astimezone(tzc).strftime('%H')<br>now.astimezone(tzu).strftime('%H')<br>

#7 所以说不是我理解有问题对不对
#8 我试试

#8 这样是 ok 了,好吧。replace 不能这么用。

但是好蛋疼啊。数据库里存的是 utf 时间戳,格式化显示的时候要根据用户浏览器、个人设置重新格式化,看来要弄个全局的 utils.timestamp_format 了

arrow 大法好,建议用 arrow
http://arrow.readthedocs.io/en/latest/

pytz 的 Asia/Shanghai 时区好像实际上会差 6 分钟。我现在都改成 dateutil.tz.gettz

#12 所以时区处理没有官方包?

翻了翻文档,给下我的实现,py3 下可以
from datetime import datetime
from datetime import timezone
from datetime import timedelta

time_format = "%Y-%m-%d %H:%M:%S"
bj_offset = timezone(timedelta(hours=8))
bj_datetime = datetime.now(bj_offset)
time = bj_datetime.strftime(time_format)

#14 就没有一个全局设置么?

比如 php date_default_timezone_set(‘Asia/Chongqing’) 之后代码 date 全是这个时区的时间

回到顶部