pytz Formatting Beijing Time 6 Minutes More Solutions

  • 2021-06-29 11:29:17
  • OfStack

start

In the django framework, the pytz library is used to handle time zone issues, so I'm also trying to use it.But we found a strange problem:


import datetime
import pytz

dt = datetime.datetime(2019,6,20, 12, tzinfo=pytz.timezone('Asia/Shanghai'))
print(dt) # 2019-06-20 12:00:00+08:06

Why is there more than 6 minutes?

Reason

This is because the time saved in pytz is local.


fmt = '%Y-%m-%d %H:%M:%S %Z%z'
dt = datetime.datetime(2019,6,20, 12, tzinfo=pytz.timezone('Asia/Shanghai'))
print(dt.strftime(fmt)) # 2019-06-20 12:00:00 LMT+0806

LMT is Local Mean Time local time, that is,'Asia/Shanghai'is an area 8 hours and 6 minutes longer than utc, not Beijing time.

Solve

So pytz provided the normalize () method to correct this problem, but instead passed in a date object without a time zone:


cn_zone = pytz.timezone('Asia/Shanghai')
dt = cn_zone.localize(dt = datetime.datetime(2019,6,20, 12))
print(dt) # 2019-06-20 12:00:00+08:00
print(dt.strftime(fmt)) # 2019-06-20 12:00:00 CST+0800

#  perhaps 
dt = datetime.datetime(2019,6,20, 12)
print(dt.astimezone(cn_zone)) # 2019-06-20 12:00:00 CST+0800

The recommended method here is astimezone, which is also used by django.

Time Zone Conversion

For example, from Beijing time to New York time, it is known that there should be a 12-hour difference between them.


dt = datetime.datetime(2019,6,20, 12)

print(dt.astimezone(tz=cn_zone)) # 2019-06-20 12:00:00+08:00
print(dt.astimezone(tz=cn_zone).astimezone(ny_zone)) # 2019-06-20 12:00:00-04:56

additional

Another time zone solution is to use the dateutil tool from the Standard Library.Official built-in, trustworthy.It supports setting the date object when it is created and is more convenient:


cn = tz.gettz('Asia/Shanghai')

aware_dt = datetime.datetime(2019,6,20, 12, tzinfo=cn)
print(aware_dt ) # 2019-06-20 12:00:00+08:00

#  Time Zone Conversion ( From Beijing Time to New York Time )
ny = tz.gettz('America/New_York')
print(aware_dt.astimezone(tz=ny)) # 2019-06-20 00:00:00-04:00

I like this way better.

summary


Related articles: