Почему appengine не конвертирует дату и время в UTC при вызове put()?

Вот что я пытаюсь сделать: пользователь отправляет время в тихоокеанском регионе, после отправки я использую .replace, чтобы установить часовой пояс на тихоокеанский.

Pacific = time.USTimeZone(-8, "Pacific",  "PST", "PDT")
addEvent.date = addEvent.date.replace(tzinfo=Pacific)

Как только я установил tzinfo, я делаю пут. В соответствии с документацией по python для google appengine говорится:

«Если значение даты и времени имеет атрибут tzinfo, оно будет преобразовано в часовой пояс UTC для хранения. Значения возвращаются из хранилища данных в формате UTC с tzinfo, равным None. Приложение, которому требуется, чтобы значения даты и времени находились в определенном часовой пояс должен правильно установить tzinfo при обновлении значения и преобразовать значения в часовой пояс при доступе к значению».

Однако, когда я делаю put(), я получаю следующую ошибку:

ПРЕДУПРЕЖДЕНИЕ 06.10.2012, 21:10:14,579 tasklets.py:399] исходный генератор _put_tasklet(context.py:264) поднял NotImplementedError(Дата DatetimeProperty может поддерживать только UTC. Создайте новое свойство для поддержки альтернативных часовых поясов.) ПРЕДУПРЕЖДЕНИЕ 2012 -10-06 21:10:14,579 tasklets.py:399] приостановленный генератор put(context.py:703) поднял NotImplementedError(Дата DatetimeProperty может поддерживать только UTC. Создайте новое свойство для поддержки альтернативных часовых поясов.)

Обратите внимание, что я использую NDB

Итак, после этого я предположил, что, возможно, NDB не преобразует его автоматически в UTC. Итак, я попытался преобразовать его в UTC, используя следующий код:

class UTC(tzinfo):
  def utcoffset(self, dt):
    return timedelta(0)
  def tzname(self, dt):
    return str("UTC")
  def dst(self, dt):
    return timedelta(0)

и теперь я все еще получаю ту же ошибку даже после того, как я конвертирую тихоокеанское время в UTC и устанавливаю имя tzinfo как «UTC».

Здесь действительно может понадобиться тонна помощи ... спасибо!


person iceanfire    schedule 06.10.2012    source источник


Ответы (3)


Решение состоит в том, чтобы полностью удалить tzinfo из времени после преобразования в UTC.

timestamp = timestamp.replace(tzinfo=None)
person Guido van Rossum    schedule 07.10.2012
comment
на самом деле пример был бы очень полезен. - person Houman; 15.01.2015
comment
Вот пример: сделайте timestamp = timestamp.replace(tzinfo=None) перед установкой для свойства значения timestamp. - person Luca; 04.04.2015
comment
Разве это не удалит информацию о часовом поясе? AFAIK ndb ожидает, что дата и время будут в формате UTC, это просто преобразует локальную дату и время с часовым поясом в локальную дату и время без часового пояса, нет? (поэтому вместо преобразования 2000-01-01T04:00:00.000000-04:00 в 2000-01-01T00:00:00.000000 он преобразует его в 2000-01-01T04:00:00.000000) - person Hans; 10.08.2017
comment
@ Ганс, он удаляет часовой пояс, но это то, что ожидает NDB. Слой NDB хранит дату и время без учета часового пояса и полагается на приложение, чтобы разобраться с преобразованием из одного часового пояса в другой. - person hamx0r; 25.04.2020

Вот мой рабочий пример:

if my_date.utcoffset():
    my_date = (my_date - my_date.utcoffset()).replace(tzinfo=None)
person Alecs    schedule 10.07.2015
comment
Возможно, измените оператор if на: если my_date.utcoffset() не None : - person MrJ; 08.09.2017

Я столкнулся с этим, используя http://hnrss.org/. Это было моим решением.

    import datetime
    from dateutil import parser

    your_date_string = 'Mon, 24 Oct 2016 16:49:47 +0000'

    your_date = parser.parse(your_date_string)
    # your_date is now a datetime.datetime object

    your_date_minus_tz = your_date.replace(tzinfo=None)

Теперь попробуйте использовать put(), и вы должны увидеть 2016-10-24 16:49:47 в хранилище данных Cloud.

person afed    schedule 21.12.2016