Как форматировать даты в валидаторе дуршлага?

Пользовательская пирамида, дуршлаг и деформация, у меня есть виджет даты и времени.

datetime_event = colander.SchemaNode(
    colander.DateTime(),
    validator=colander.Range(
        min=datetime(
            2018, 1, 1, 0, 0,
            tzinfo=timezone.utc),
        min_err=(
            '${val} must be after ${min}'),
        max=datetime.now(timezone.utc),
        max_err=(
            '${val} is in the future, and must be less than ${max}')
    ),
)

Я получаю это сообщение об ошибке проверки, враждебное пользователю.

2017-08-21 05:00:00-07:53 должно быть после 2018-01-01 00:00:00+00:00

Я хотел бы отформатировать дату без часового пояса:

2017-08-21 05:00:00 должно быть после 2018-01-01 00:00:00

Или еще лучше:

21 августа 2017 г. 5:00 должно быть после 12:00 1 января 2018 г.

Если возможно, как мне отформатировать объекты даты и времени в min_err и max_err?


person Steve Piercy    schedule 25.09.2018    source источник
comment
-07:53 так как часовой пояс выглядит совсем не так   -  person Antti Haapala    schedule 05.10.2018
comment
Эта зона предполагает, что вы используете pytz без должной нормализации   -  person Antti Haapala    schedule 05.10.2018
comment
Конечно. После того, как я задал вопрос, я узнал, что у pytz есть список часовых поясов в _tzinfos, включая устаревшее среднее местное время (LMT), которое стало использоваться по умолчанию, поскольку оно находится первым в списке. В конце концов я все это проработал, как показано в моем ответе ниже.   -  person Steve Piercy    schedule 05.10.2018
comment
Связанный: opensourcehacker.com /2008/06/30/   -  person Antti Haapala    schedule 05.10.2018


Ответы (1)


Вот что я в итоге использовал. Ключевым моментом было не использовать переменную по умолчанию ${val}, а использовать простые старые f-строки Python.

tz = self.tz
days_before = 28
dtmin = local_days_before(tz, days_before)  # localized min date
dtmax = datetime.now(utc).astimezone(tz)
datetime_event = colander.SchemaNode(
    colander.DateTime(default_tzinfo=dtmax.tzinfo),
    widget=deform.widget.DateTimeInputWidget(
        date_options={'min': -days_before,
                      'max': True,
                      'format': 'yyyy-mm-dd'},
        time_options={'format': 'HH:i',
                      'formatLabel': 'HH:i'},
    ),
    validator=colander.Range(
        min=dtmin,
        min_err=(f"Datetime must be after "
                 f"{dtmin:%B %d, %Y, %-I:%M %p} "),
        max=dtmax,
        max_err=(f"Datetime must be before "
                 f"{dtmax: %B %d, %Y, %-I:%M %p}")
    ),
    title='Date and Time',
    description='Date and time when the event occurred'
)

Это решение также реализует форматирование даты и времени, а также минимальных и максимальных дат в пользовательском интерфейсе pickadate.

person Steve Piercy    schedule 27.09.2018