-2

I have a class:

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?

I'd like to get nearest start at future. E.g if in starts_at stored 10:00 AM and in day_of week stored Friday and today is Friday 10:30 I want to get 10:00 AM of next Friday. How to do this?

Vassily
  • 5,263
  • 4
  • 33
  • 63
  • Check what weekday it's now https://stackoverflow.com/questions/9847213/how-do-i-get-the-day-of-week-given-a-date-in-python If db_weekday > now_weekday return future weekday, else return db_weekday – Adelina Jul 28 '18 at 14:10

1 Answers1

0

I always reach for python-dateutil in things like this, since they've done the figuring out.

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()
Chris Curvey
  • 9,738
  • 10
  • 48
  • 70