Значение даты выходит за пределы диапазона при локализации даты и времени

Я пытаюсь локализовать строку времени как часовой пояс с помощью Python и сохранить данные в монго.

Но когда я попытался локализовать время с помощью функции Asia/Taipei, я получил следующую ошибку: localize, я думаю, это может быть из-за того, что время, которое я пытался установить, является максимальным пределом: OverflowError: date value out of range, потому что, пока я устанавливаю другую строку времени, например 9999/12/31, она работает отлично .

Итак, я попытался установить время с помощью функции 2024/01/01, но получил неправильный результат часового пояса, поскольку .replace(tzinfo=tz) не правильный UTC +08:06.

В настоящее время я применил метод 3, добавив 6 минут к дате и времени после замены часового пояса, но я не уверен, что это хороший метод.

Есть ли у вас какие-либо предложения по установке времени в правильном часовом поясе? Любое предложение приветствуется, вот мой код:


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

Какова цель 9999 года? Если вам нравится представлять что-то вроде «недействительного», используйте null. В противном случае 2999 год, безусловно, тоже подошёл бы.

Wernfried Domscheit 10.05.2024 09:07

Как этот вопрос связан с MongoDB?

Wernfried Domscheit 10.05.2024 09:08

@WernfriedDomscheit Я думаю, что они проверяют преобразование UTC, поскольку MongoDB хранит дату и время в формате UTC, а их текущий объект, поддерживающий tz, преобразуется неправильно. Что касается «цели года 9999», он используется в качестве даты окончания/высшей даты в определенных системах управления персоналом/расчета заработной платы. Также используется как дата бесконечного будущего, поскольку в большинстве систем/языков нет +Date.inf. И null должен обозначать либо неизвестное, либо недействительное; но не известное бесконечное будущее.

aneroid 10.05.2024 09:58
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
3
80
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Начиная с Python 3.9, PyTZ устарел. Вместо этого используйте zoneinfo из стандартной библиотеки :

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)

Кроме того, я бы рекомендовал вам сохранить верхнюю дату 9999-12-31 в формате UTC и в полночь. В противном случае локализованное преобразование из разных мест всегда будет происходить в разное время 30 или 31 декабря, что приведет к разному времени в базе данных для одной и той же даты.

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

В идеале верхняя дата также должна быть 23:59:59 31 декабря 9999 года, но если это указано в формате UTC, то все часовые пояса перед UTC, например Тайбэй, будут переполнены.

Другие вопросы по теме