Время немного уменьшается при добавлении в базу данных - PullRequest
2 голосов
/ 15 июня 2019

Я пытаюсь создать дополнительные слоты для встреч в моей базе данных программным способом, но я заметил, что мои значения для date_start и date_end немного отключены.

То, что я сделал, - это магазин в будние и выходные дни.временные интервалы в массивах пар кортежей.Кортежи содержат значение часа и минуты, которые передаются в качестве параметра внутренней функции appointments, где они распаковываются и передаются в конструктор datetime.

Manager.py

Речь идет о функции create_appointments (в частности, appointments), в которой жестко заданы временные интервалы и для каждой пары вызывается create_appointment.

import pytz

from django.db import models
from datetime import date, datetime
from project.settings import TIME_ZONE # 'America/Chicago'


class AppointmentManager(models.Manager):
    def create_appointment(self, date_start, date_end):
        from booking.models import Appointment

        try:
            appt = Appointment.objects.create(
                profile=None,
                date_start=date_start,
                date_end=date_end,
            )
        except Exception as e:
            return (False, e)
        return (True, appt)


    def create_appointments(self, date=date.today(), tzinfo=pytz.timezone(TIME_ZONE), verbose=False):
        from booking.models import Appointment

        def appointments(times):
            for pair in times:
                hour_start, minute_start = pair[0]
                hour_end, minute_end = pair[1]

                date_start = datetime(
                    date.year,
                    date.month,
                    date.day,
                    hour_start,
                    minute_start,
                    tzinfo=tzinfo,
                )

                date_end = datetime(
                    date.year,
                    date.month,
                    date.day,
                    hour_end,
                    minute_end,
                    tzinfo=tzinfo,
                )

                valid, response = self.create_appointment(date_start, date_end)

                if not valid:
                    raise response

                if verbose:
                    print('%s %s' % (response.date_start, response.date_end))


        def weekend():
            appointments([
                [ (8, 0),  (8, 50)], #  8am
                [ (9, 0),  (9, 50)], #  9am
                [(10, 0), (10, 50)], # 10am
                [(11, 0), (11, 50)], # 11am

                [(13, 0), (13, 50)], #  1pm
                [(14, 0), (14, 50)], #  2pm
                [(15, 0), (15, 50)], #  3pm

                [(17, 0), (17, 50)], #  5pm
                [(18, 0), (18, 50)], #  6pm
                [(19, 0), (19, 50)], #  7pm
            ])


        def weekday():
            appointments([
                [(17, 0), (17, 50)], # 5pm
                [(18, 0), (18, 50)], # 6pm
                [(19, 0), (19, 50)], # 7pm
            ])


        options = {
            0: weekday,
            1: weekday,
            2: weekday,
            3: weekday,
            4: weekday,
            5: weekend,
            6: weekend,
        }

        try:
            options[date.weekday()]()
        except Exception as e:
            return (False, e)
        return (True, Appointment.objects.filter(
            date_start__year=date.year,
            date_start__month=date.month,
            date_start__day=date.day,
        ))

Когда я запускаю с включенным флагом многословия, я получаю следующее:

Ожидаемый результат:

2019-06-15 08:00:00-05:00 2019-06-15 08:50:00-05:00
2019-06-15 09:00:00-05:00 2019-06-15 09:50:00-05:00
2019-06-15 10:00:00-05:00 2019-06-15 10:50:00-05:00
…
2019-06-21 17:00:00-05:00 2019-06-21 17:50:00-05:00
2019-06-21 18:00:00-05:00 2019-06-21 18:50:00-05:00
2019-06-21 19:00:00-05:00 2019-06-21 19:50:00-05:00

Фактический результат:

2019-06-15 08:00:00-05:51 2019-06-15 08:50:00-05:51
2019-06-15 09:00:00-05:51 2019-06-15 09:50:00-05:51
2019-06-15 10:00:00-05:51 2019-06-15 10:50:00-05:51
…
2019-06-21 17:00:00-05:51 2019-06-21 17:50:00-05:51
2019-06-21 18:00:00-05:51 2019-06-21 18:50:00-05:51
2019-06-21 19:00:00-05:51 2019-06-21 19:50:00-05:51

Таким образом, базовое время правильное, а смещение часового пояса - нет.Почему я постоянно получаю это ложное значение?

Я использую SQLite для разработки и планирую использовать PostgreSQL для производства.

1 Ответ

2 голосов
/ 15 июня 2019
>>> pytz.timezone("America/Chicago")
<DstTzInfo 'America/Chicago' LMT-1 day, 18:09:00 STD>
>>> offset = 24*3600 - 18*3600 - 9*60
>>> (offset//3600, offset//60%60)
(5, 51)

использование pytz.timezone для установки tzinfo будет использовать более старую систему часовых поясов, которую мы используем сегодня, .localize, кажется, решает эту проблему и должна использоваться вместо нее.

>>> # pytz.timezone(...).localize(datetime(...))
>>> pytz.timezone("America/Chicago").localize(datetime.datetime(2019, 6, 15, 17, 00)).isoformat(" ")
'2019-06-15 17:00:00-05:00'

вместо

>>> # datetime(..., tzinfo=pytz.timezone(...))
>>> datetime.datetime(2019, 6, 15, 17, 00, tzinfo=pytz.timezone("America/Chicago")).isoformat(" ")
'2019-06-15 17:00:00-05:51'

edit: кстати, не используйте экземпляры объектов в качестве аргумента по умолчанию, например date=date.today()

date.today () вызывается при создании функции, и полученный объект будет повторно использован. если сценарий будет выполняться более одного дня, он все равно будет использовать дату предыдущего дня. используйте вместо этого следующую конструкцию.

def create_appointments(self, date=None, tzinfo=pytz.timezone(TIME_ZONE), verbose=False):
    if date is None:
        date = date.today()
    ...
...