添加到数据库时时间值略有偏差
Time values off slightly when adding to database
我正在尝试以编程方式向我的数据库创建一个添加预约时段,但我注意到 date_start
和 date_end
的值略有偏差。
我所做的是将工作日和周末时间段存储在元组对的数组中。元组包含一个小时和一个分钟值,它们作为参数传递给内部 appointments
函数,在那里它们被解包并传递给 datetime
构造函数。
managers.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 进行生产。
>>> 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'
编辑:顺便说一句,不要使用对象的实例作为默认参数,例如 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()
...
我正在尝试以编程方式向我的数据库创建一个添加预约时段,但我注意到 date_start
和 date_end
的值略有偏差。
我所做的是将工作日和周末时间段存储在元组对的数组中。元组包含一个小时和一个分钟值,它们作为参数传递给内部 appointments
函数,在那里它们被解包并传递给 datetime
构造函数。
managers.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 进行生产。
>>> 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'
编辑:顺便说一句,不要使用对象的实例作为默认参数,例如 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()
...