<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -39,21 +39,20 @@ OCCURRENCE_CLASS_CSS = {
     OCCURRENCE_STARTS_ENDS: OCCURRENCE_CLASS_CSS_VALUES[3],
 }
 
+def get_weekday_names_and_abbrs(first_day_of_week):
+    &quot;&quot;&quot;Utility function to get shifted days of the week.
 
-weekday_names = []
-weekday_abbrs = []
-if FIRST_DAY_OF_WEEK == 1:
-    # The calendar week starts on Monday
+    first_day_of_week is 0/Sun based.
+    &quot;&quot;&quot;
+    names = []
+    abbrs = []
     for i in range(7):
-        weekday_names.append( WEEKDAYS[i] )
-        weekday_abbrs.append( WEEKDAYS_ABBR[i] )
-else:
-    # The calendar week starts on Sunday, not Monday
-    weekday_names.append( WEEKDAYS[6] )
-    weekday_abbrs.append( WEEKDAYS_ABBR[6] )
-    for i in range(6):
-        weekday_names.append( WEEKDAYS[i] )
-        weekday_abbrs.append( WEEKDAYS_ABBR[i] )
+        # -1 shift since WEEKDAYS* data is based on FDOW=1/Mon
+        i = (i - 1 + first_day_of_week) % 7
+        names.append( WEEKDAYS[i] )
+        abbrs.append( WEEKDAYS_ABBR[i] )
+    return (names, abbrs)
+(weekday_names, weekday_abbrs) = get_weekday_names_and_abbrs(FIRST_DAY_OF_WEEK)
 
 
 class Period(object):
@@ -305,18 +304,9 @@ class Week(Period):
             week = week.date()
         # Adjust the start datetime to midnight of the week datetime
         start = datetime.datetime.combine(week, datetime.time.min)
-        # Adjust the start datetime to Monday or Sunday of the current week
-        sub_days = 0
-        if FIRST_DAY_OF_WEEK == 1:
-            # The week begins on Monday
-            sub_days = start.isoweekday() - 1
-        else:
-            # The week begins on Sunday
-            sub_days = start.isoweekday()
-            if sub_days == 7:
-                sub_days = 0
-        if sub_days &gt; 0:
-            start = start - datetime.timedelta(days=sub_days)
+        shift_to_fdow = (start.isoweekday() - FIRST_DAY_OF_WEEK) % 7
+        if shift_to_fdow &gt; 0:
+            start = start - datetime.timedelta(days=shift_to_fdow)
         end = start + datetime.timedelta(days=7)
         return start, end
 </diff>
      <filename>schedule/periods.py</filename>
    </modified>
    <modified>
      <diff>@@ -7,7 +7,7 @@ from django.core.urlresolvers import reverse
 
 from schedule.conf.settings import FIRST_DAY_OF_WEEK
 from schedule.models import Event, Rule, Occurrence, Calendar
-from schedule.periods import Period, Month, Week, Day, Year
+from schedule.periods import Period, Month, Week, Day, Year, get_weekday_names_and_abbrs
 from schedule.periods import OCCURRENCE_SPANS, OCCURRENCE_STARTS, OCCURRENCE_ENDS, OCCURRENCE_STARTS_ENDS
 from schedule.utils import EventListManager
 
@@ -22,7 +22,7 @@ class TestPeriod(TestCase):
                 'title': 'Recent Event',
                 'start': datetime.datetime(2008, 1, 5, 8, 0),
                 'end': datetime.datetime(2008, 1, 5, 9, 0),
-                'end_recurring_period' : datetime.datetime(2008, 5, 5, 0, 0),
+                'end_recurring_period': datetime.datetime(2008, 5, 5, 0, 0),
                 'rule': rule,
                 'calendar': cal
                }
@@ -30,7 +30,7 @@ class TestPeriod(TestCase):
             'title': '3-Day Event',
             'start': datetime.datetime(2008, 1, 1, 8, 0),
             'end': datetime.datetime(2008, 1, 3, 9, 0),
-            'end_recurring_period' : datetime.datetime(2008, 5, 5, 0, 0),
+            'end_recurring_period': datetime.datetime(2008, 5, 5, 0, 0),
             'calendar': cal
             }
         recurring_event = Event(**data)
@@ -40,10 +40,10 @@ class TestPeriod(TestCase):
         three_day_event.save()
         self.three_day_event = three_day_event
         self.period = Period(events=Event.objects.all(),
-                            start = datetime.datetime(2008,1,4,7,0),
-                            end = datetime.datetime(2008,1,21,7,0))
+                             start=datetime.datetime(2008, 1, 4, 7, 0),
+                             end=datetime.datetime(2008, 1, 21, 7, 0))
         self.week_period = Week(events=Event.objects.all(),
-                                date=three_day_event.start)
+                                date=datetime.datetime(2008, 1, 5))
 
     def test_get_occurrences(self):
         occurrence_list = self.period.occurrences
@@ -81,8 +81,8 @@ class TestPeriod(TestCase):
 
     def test_has_occurrence(self):
         self.assert_( self.period.has_occurrences() )
-        slot = self.period.get_time_slot( datetime.datetime(2008,1,4,7,0),
-                                          datetime.datetime(2008,1,4,7,12) )
+        slot = self.period.get_time_slot( datetime.datetime(2008, 1, 4, 7, 0),
+                                          datetime.datetime(2008, 1, 4, 7, 12) )
         self.failIf( slot.has_occurrences() )
 
     def test_occurrence_classes(self):
@@ -94,10 +94,11 @@ class TestPeriod(TestCase):
         self.assertEqual(OCCURRENCE_STARTS_ENDS, single_day_occ[&quot;class&quot;])
 
         week = self.week_period
-        # week's events look like this:
-        # Su Mu Tu We Th Fr Sa Su
-        # -- -- e1 e1 e1 -- e2 --
-        # (extra Sunday included to allow for fdow = 0 or 1)
+        # week's + next 6 days events look like this:
+        # Su Mu Tu We Th Fr Sa
+        # -- -- e1 e1 e1 -- e2
+        # -- -- -- -- -- --
+        # (extra 6 days included to allow for FIRST_DAY_OF_WEEK 1..6)
 
         e1 = self.three_day_event
         e2 = self.recurring_event
@@ -108,10 +109,15 @@ class TestPeriod(TestCase):
                     (e1,OCCURRENCE_ENDS),
                     (None,None),
                     (e2,OCCURRENCE_STARTS_ENDS),
+                    # next 6 items are only used for FIRST_DAY_OF_WEEK &gt; 0
+                    (None,None),
+                    (None,None),
+                    (None,None),
+                    (None,None),
+                    (None,None),
+                    (None,None),
                     ]
-        if FIRST_DAY_OF_WEEK == 1:
-            # just wrapping the empty sunday around if the fdow is monday
-            expected = expected[1:] + expected[:1]
+        expected = expected[FIRST_DAY_OF_WEEK:FIRST_DAY_OF_WEEK+7]
         for (expect, day) in zip(expected, week.get_days()):
             (expected_event, expected_occ_class) = expect
             expecting_occurrences = not expected_event is None
@@ -121,6 +127,7 @@ class TestPeriod(TestCase):
                 self.assertEqual(expected_occ_class, occ['class'])
                 self.assertEqual(expected_event, occ['occurrence'].event)
 
+
 class TestYear(TestCase):
 
     def setUp(self):
@@ -128,13 +135,24 @@ class TestYear(TestCase):
 
     def test_get_months(self):
         months = self.year.get_months()
+        expected_months = [datetime.datetime(2008, i, 1) for i in range(1,13)]
         self.assertEqual([month.start for month in months],
-            [datetime.datetime(2008, i, 1) for i in range(1,13)])
+                         expected_months)
 
 
 class TestMonth(TestCase):
 
     def setUp(self):
+        &quot;&quot;&quot;
+        For reference:
+           February 2008
+        Su Mo Tu We Th Fr Sa
+        27 28 29 30 31  1  2
+         3  4  5  6  7  8  9
+        10 11 12 13 14 15 16
+        17 18 19 20 21 22 23
+        24 25 26 27 28 29
+        &quot;&quot;&quot;
         rule = Rule(frequency = &quot;WEEKLY&quot;)
         rule.save()
         cal = Calendar(name=&quot;MyCal&quot;)
@@ -143,7 +161,7 @@ class TestMonth(TestCase):
                 'title': 'Recent Event',
                 'start': datetime.datetime(2008, 1, 5, 8, 0),
                 'end': datetime.datetime(2008, 1, 5, 9, 0),
-                'end_recurring_period' : datetime.datetime(2008, 5, 5, 0, 0),
+                'end_recurring_period': datetime.datetime(2008, 5, 5, 0, 0),
                 'rule': rule,
                 'calendar': cal
                }
@@ -155,81 +173,37 @@ class TestMonth(TestCase):
     def test_get_weeks(self):
         weeks = self.month.get_weeks()
         actuals = [(week.start,week.end) for week in weeks]
-
-        if FIRST_DAY_OF_WEEK == 0:
-            expecteds = [
-                (datetime.datetime(2008, 1, 27, 0, 0),
-                 datetime.datetime(2008, 2, 3, 0, 0)),
-                (datetime.datetime(2008, 2, 3, 0, 0),
-                 datetime.datetime(2008, 2, 10, 0, 0)),
-                (datetime.datetime(2008, 2, 10, 0, 0),
-                 datetime.datetime(2008, 2, 17, 0, 0)),
-                (datetime.datetime(2008, 2, 17, 0, 0),
-                 datetime.datetime(2008, 2, 24, 0, 0)),
-                (datetime.datetime(2008, 2, 24, 0, 0),
-                 datetime.datetime(2008, 3, 2, 0, 0))
-            ]
-        else:
-            expecteds = [
-                (datetime.datetime(2008, 1, 28, 0, 0),
-                 datetime.datetime(2008, 2, 4, 0, 0)),
-                (datetime.datetime(2008, 2, 4, 0, 0),
-                 datetime.datetime(2008, 2, 11, 0, 0)),
-                (datetime.datetime(2008, 2, 11, 0, 0),
-                 datetime.datetime(2008, 2, 18, 0, 0)),
-                (datetime.datetime(2008, 2, 18, 0, 0),
-                 datetime.datetime(2008, 2, 25, 0, 0)),
-                (datetime.datetime(2008, 2, 25, 0, 0),
-                 datetime.datetime(2008, 3, 3, 0, 0))
-            ]
-
+        seven_days = datetime.timedelta(days=7)
+        # wierd -1 shift is for saturday the 2nd
+        fdow_shift = datetime.timedelta(days=FIRST_DAY_OF_WEEK if FIRST_DAY_OF_WEEK &lt; 6 else -1)
+        fdows = [datetime.datetime(2008, m, d) + fdow_shift
+                 for (m,d) in [(1,27),
+                               (2, 3),
+                               (2,10),
+                               (2,17),
+                               (2,24)]]
+        expecteds = [(day, day + seven_days) for day in fdows]
         for actual, expected in zip(actuals, expecteds):
             self.assertEqual(actual, expected)
 
     def test_get_days(self):
         weeks = self.month.get_weeks()
         week = list(weeks)[0]
-        days = week.get_days()
-        actuals = [(len(day.occurrences), day.start,day.end) for day in days]
-
-        if FIRST_DAY_OF_WEEK == 0:
-            expecteds = [
-                (0, datetime.datetime(2008, 1, 27, 0, 0),
-                 datetime.datetime(2008, 1, 28, 0, 0))
-                (0, datetime.datetime(2008, 1, 28, 0, 0),
-                 datetime.datetime(2008, 1, 29, 0, 0)),
-                (0, datetime.datetime(2008, 1, 29, 0, 0),
-                 datetime.datetime(2008, 1, 30, 0, 0)),
-                (0, datetime.datetime(2008, 1, 30, 0, 0),
-                 datetime.datetime(2008, 1, 31, 0, 0)),
-                (0, datetime.datetime(2008, 1, 31, 0, 0),
-                 datetime.datetime(2008, 2, 1, 0, 0)),
-                (0, datetime.datetime(2008, 2, 1, 0, 0),
-                 datetime.datetime(2008, 2, 2, 0, 0)),
-                (1, datetime.datetime(2008, 2, 2, 0, 0),
-                 datetime.datetime(2008, 2, 3, 0, 0)),
-            ]
-
-        else:
-            expecteds = [
-                (0, datetime.datetime(2008, 1, 28, 0, 0),
-                 datetime.datetime(2008, 1, 29, 0, 0)),
-                (0, datetime.datetime(2008, 1, 29, 0, 0),
-                 datetime.datetime(2008, 1, 30, 0, 0)),
-                (0, datetime.datetime(2008, 1, 30, 0, 0),
-                 datetime.datetime(2008, 1, 31, 0, 0)),
-                (0, datetime.datetime(2008, 1, 31, 0, 0),
-                 datetime.datetime(2008, 2, 1, 0, 0)),
-                (0, datetime.datetime(2008, 2, 1, 0, 0),
-                 datetime.datetime(2008, 2, 2, 0, 0)),
-                (1, datetime.datetime(2008, 2, 2, 0, 0),
-                 datetime.datetime(2008, 2, 3, 0, 0)),
-                (0, datetime.datetime(2008, 2, 3, 0, 0),
-                 datetime.datetime(2008, 2, 4, 0, 0))
-            ]
+        days = list(week.get_days())
 
-        for actual, expected in zip(actuals, expecteds):
-            self.assertEqual(actual, expected)
+        # wierd -1 shift is for saturday the 2nd
+        fdow_shift = datetime.timedelta(days=FIRST_DAY_OF_WEEK if FIRST_DAY_OF_WEEK &lt; 6 else -1)
+        expected_fdow = datetime.datetime(2008, 1, 27) + fdow_shift
+        self.assertEqual(days[0].start, expected_fdow)
+        # expecting 1 occurrence on the 2nd, 0 otherwise.
+        only_day_with_occurrences = datetime.datetime(2008, 2, 2)
+
+        for day in days:
+            expected_occurrences = 1 if day.start == only_day_with_occurrences else 0
+            self.assertEqual(len(day.occurrences), expected_occurrences,
+                             &quot;Expected %d != %d on %s&quot; % (len(day.occurrences),
+                                                          expected_occurrences,
+                                                          day.start))
 
 
     def test_month_convenience_functions(self):
@@ -290,3 +264,17 @@ class TestOccurrencePool(TestCase):
         period = Period(parent_period.events, start, end, parent_period.get_persisted_occurrences(), parent_period.occurrences)
         self.assertEquals(parent_period.occurrences, period.occurrences)
 
+class TestOther(TestCase):
+
+    def setUp(self):
+        pass
+
+    def test_get_weekday_names_and_abbrs(self):
+        from django.utils.dates import WEEKDAYS, WEEKDAYS_ABBR
+        for i in range(7):
+            # just spot checking first value for each FDOW offset 0..6
+            (names, abbrs) = get_weekday_names_and_abbrs(i)
+            self.assertEquals((i, WEEKDAYS[(i-1)%7].format(&quot;%s&quot;)),
+                              (i, names[0].format(&quot;%s&quot;)))
+            self.assertEquals((i, WEEKDAYS_ABBR[(i-1)%7].format(&quot;%s&quot;)),
+                              (i, abbrs[0].format(&quot;%s&quot;)))</diff>
      <filename>schedule/tests/test_periods.py</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>a3b8fc13c6f9a7f844557d1046e93ebd7239fb33</id>
    </parent>
  </parents>
  <author>
    <name>Ian Struble</name>
    <email>istruble@gmail.com</email>
  </author>
  <url>http://github.com/istruble/django-schedule/commit/6fd023e3ed82790ecc8dfa9233b6318a64b20d37</url>
  <id>6fd023e3ed82790ecc8dfa9233b6318a64b20d37</id>
  <committed-date>2009-10-04T23:34:46-07:00</committed-date>
  <authored-date>2009-10-04T23:34:46-07:00</authored-date>
  <message>FIRST_DAY_OF_WEEK now supports 0..6.

The error message for FDOW in schedule/conf/settings.py suggests
that numbers from 0 to 6 are valid.  The code now backs this up.
Not that anyone really uses values of 2..6 in real life.

 - Refactored some of the FDOW logic in periods.py to support 0..6
   instead of just 0 and 1.  The FDOW shifting logic is simpler now.

 - Updated tests in test_periods.py to be able to handle 2..6 values.
   Changes were very similar to changes in periods.py in two cases but
   not the same.  Mostly just more use of modulo 7 math instead of
   &quot;if 1: ... else: ...&quot; code.</message>
  <tree>45d276a23ce103e2e66a56ae668cc08b955b3914</tree>
  <committer>
    <name>Ian Struble</name>
    <email>istruble@gmail.com</email>
  </committer>
</commit>
