如何从列表中获取最近的时间?

时间:2018-07-28 13:57:17

标签: python django datetime

我有一堂课

class ScheduleEntry(models.Model):
    DOW_CHOICES = (
        (1, _("Monday")),
        (2, _("Tuesday")),
        (3, _("Wednesday")),
        (4, _("Thursday")),
        (5, _("Friday")),
        (6, _("Saturday")),
        (7, _("Sunday")),
    )
    starts_at = models.TimeField(verbose_name=_("Starts at"))
    day_of_week = models.PositiveSmallIntegerField(choices=DOW_CHOICES, verbose_name=_("Day of week"))

    def next_start(self):
        # what is here?

我希望将来能有更接近的起点。例如,如果在starts_at中存储的是上午10:00,而在day_of week中存储的是星期五,今天是星期五10:30,我想获得下周五的10:00 AM。这该怎么做?

1 个答案:

答案 0 :(得分:0)

在这样的事情上,我总是向python-dateutil伸出援手,因为他们已经弄清楚了。

import unittest
from datetime import datetime, time

from dateutil import rrule

class ScheduleEntry(object):
    def __init__(self, starts_at, day_of_week):
        self.starts_at = starts_at
        self.day_of_week = day_of_week

    def next_start(self, now=None):
        # the "now" bit is just for testing.
        if now is None:
            now = datetime.now()

        # build a rule that will get the next day_of_week after the current 
        # time
        rule = rrule.rrule(dtstart=now, count=1, freq=rrule.WEEKLY,
                           byweekday=self.day_of_week, 
                           byhour=self.starts_at.hour, 
                           byminute=self.starts_at.minute)

        # run the value from the rule
        return list(rule)[0]

MONDAY = 0
class TestNextStart(unittest.TestCase):
    def test_next_monday_10am(self):
        sched = ScheduleEntry(starts_at=time(10, 00), day_of_week=MONDAY)

        july_30_9am = datetime(year=2018, month=07, day=30, hour=9)
        july_30_10am = datetime(year=2018, month=07, day=30, hour=10)
        assert sched.next_start(now=july_30_9am) == july_30_10am

        july_30_11am = datetime(year=2018, month=07, day=30, hour=11)
        aug_6_10am = datetime(year=2018, month=8, day=6, hour=10)
        assert sched.next_start(now=july_30_11am) == aug_6_10am


if __name__ == '__main__':
    unittest.main()