I am trying to localize a time string as Asia/Taipei
timezone by python, and save the data to mongo.
But when I tried to localize the time by localize
function, I got following error: OverflowError: date value out of range
, I think it might because of the time I tried to set is the max limit: 9999/12/31
, cause while I set other time string like 2024/01/01
it works perfectly.
So I tried to set the time by .replace(tzinfo=tz)
function, but got an incorrect result of time zone as UTC +08:06
not the correct +08:00
.
Currently I applied method 3, add 6 minutes to the date time after replace timezone, but I am not sure if it's a good method.
Do you have any suggestions to set the time the the correct timezone? Any suggestion is welcome, following is my code:
import pytz
from datetime import datetime, date
tz = pytz.timezone('Asia/Taipei')
date_string = '9999/12/31'
# method 1
# date_localized = datetime.strptime(date_string, '%Y/%m/%d')
# date_localized = tz.localize(date_localized)
# OverflowError: date value out of range
# method 2
date_localized = datetime.strptime(date_string, '%Y/%m/%d').replace(tzinfo=tz)
# 9999-12-30T15:54:00.000+00:00 in mongo
# method 3
date_localized = datetime.strptime(date_string, '%Y/%m/%d').replace(tzinfo=tz)
tag_disableDtm = tag_disableDtm + timedelta(minutes=6)
# 9999-12-30T16:00:00.000+00:00 in mongo
As of Python 3.9, PyTZ is deprecated. Use zoneinfo
from the standard library instead:
from datetime import datetime, timezone
from zoneinfo import ZoneInfo
tz = ZoneInfo('Asia/Taipei')
date_string = '9999/12/31'
# method 2
date_localized = datetime.strptime(date_string, '%Y/%m/%d').replace(tzinfo=tz)
# datetime.datetime(9999, 12, 31, 0, 0, tzinfo=zoneinfo.ZoneInfo(key='Asia/Taipei'))
# 9999-12-30T16:00:00.000+00:00 in MongoDB
date_localized.astimezone(timezone.utc)
# datetime.datetime(9999, 12, 30, 16, 0, tzinfo=datetime.timezone.utc)
Also, I would recommend that you store the High Date 9999-12-31 as UTC and at midnight. Otherwise the localised conversion from different locations will always be different times on 30th or 31st Dec, leading to different times in the DB for that same date.
HIGH_DATE = datetime(9999, 12, 31, tzinfo=timezone.utc)
HIGH_DATE.astimezone(ZoneInfo('Asia/Taipei'))
# datetime.datetime(9999, 12, 31, 8, 0, tzinfo=zoneinfo.ZoneInfo(key='Asia/Taipei'))
# 9999-12-31T00:00:00.000+00:00 in MongoDB
datetime(9999, 12, 31, 8, tzinfo=ZoneInfo('Asia/Taipei')) == HIGH_DATE
# True
datetime.strptime('9999/12/31 8:0:0', '%Y/%m/%d %H:%M:%S').replace(tzinfo=tz) == HIGH_DATE
# True
Ideally, High date should also be 11:59:59 PM on 31st Dec 9999 but if that's in UTC then all timezones ahead of UTC, like Taipei, would overflow.