<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -394,11 +394,19 @@ class RecurringTodo &lt; ActiveRecord::Base
     # the due date in time)
     # 
     # assumes self.recurring_period == 'daily'
+  
+    # determine start
     if previous.nil?
       start = self.start_from.nil? ? Time.now.utc : self.start_from
     else
       # use the next day
       start = previous + 1.day
+
+      unless self.start_from.nil?
+        # check if the start_from date is later than previous. If so, use
+        # start_from as start to search for next date
+        start = self.start_from if self.start_from &gt; previous 
+      end
     end
 
     if self.only_work_days
@@ -419,6 +427,7 @@ class RecurringTodo &lt; ActiveRecord::Base
   end
   
   def get_weekly_date(previous)
+    # determine start
     if previous == nil
       start = self.start_from.nil? ? Time.now.utc : self.start_from
     else
@@ -428,7 +437,13 @@ class RecurringTodo &lt; ActiveRecord::Base
         # that week
         start += self.every_other1.week
       end
+      unless self.start_from.nil?
+        # check if the start_from date is later than previous. If so, use
+        # start_from as start to search for next date
+        start = self.start_from if self.start_from &gt; previous 
+      end
     end
+    
     # check if there are any days left this week for the next todo
     start.wday().upto 6 do |i|
       return start + (i-start.wday()).days unless self.every_day[i,1] == ' '
@@ -447,11 +462,8 @@ class RecurringTodo &lt; ActiveRecord::Base
   end
   
   def get_monthly_date(previous)
-    if previous.nil?
-      start = self.start_from.nil? ? Time.now.utc : self.start_from
-    else
-      start = previous
-    end
+    
+    start = determine_start(previous)
     day = self.every_other1
     n = self.every_other2
     
@@ -505,18 +517,8 @@ class RecurringTodo &lt; ActiveRecord::Base
   end
   
   def get_yearly_date(previous)
-    if previous.nil?
-      start = self.start_from.nil? ? Time.now.utc : self.start_from
-    else
-      if self.start_from.nil?
-        start = previous
-      else
-        # check if the start_from date is later than previous. If so, use
-        # start_from as start to search for next date
-        start = self.start_from &gt; previous ? self.start_from : previous
-      end
-    end
 
+    start = determine_start(previous)
     day = self.every_other1
     month = self.every_other2
     
@@ -598,4 +600,19 @@ class RecurringTodo &lt; ActiveRecord::Base
     errors.add(&quot;&quot;, &quot;At least one day must be selected in the weekly pattern&quot;) if self.every_day == '       '
   end
   
+  def determine_start(previous)
+    if previous.nil?
+      start = self.start_from.nil? ? Time.now.utc : self.start_from
+    else
+      start = previous
+
+      unless self.start_from.nil?
+        # check if the start_from date is later than previous. If so, use
+        # start_from as start to search for next date
+        start = self.start_from if self.start_from &gt; previous 
+      end
+    end
+    return start
+  end
+  
 end</diff>
      <filename>app/models/recurring_todo.rb</filename>
    </modified>
    <modified>
      <diff>@@ -34,23 +34,13 @@ class RecurringTodoTest &lt; Test::Rails::TestCase
   def test_daily_every_day
     # every_day should return todays date if there was no previous date
     due_date = @every_day.get_due_date(nil)
-    # use to_s in compare, because milisec could be different
-    assert_equal @today.to_s, due_date.to_s
+    # use strftime in compare, because milisec / secs could be different
+    assert_equal @today.strftime(&quot;%d-%m-%y&quot;), due_date.strftime(&quot;%d-%m-%y&quot;)
 
     # when the last todo was completed today, the next todo is due tomorrow
     due_date =@every_day.get_due_date(@today)
     assert_equal @tomorrow, due_date
-    
-    # every_day should return start_day if it is in the future
-    @every_day.start_from = @in_three_days
-    due_date = @every_day.get_due_date(nil)
-    assert_equal @in_three_days, due_date
-    
-    # if we give a date in the future for the previous todo, the next to do
-    # should be based on that future date.
-    due_date = @every_day.get_due_date(@in_four_days)
-    assert_equal @in_four_days+1.day, due_date    
-    
+        
     # do something every 14 days
     @every_day.every_other1=14
     due_date = @every_day.get_due_date(@today)
@@ -168,7 +158,6 @@ class RecurringTodoTest &lt; Test::Rails::TestCase
     
     due_date = @monthly.get_due_date(@sunday) # june 8th
     assert_equal Time.utc(2008,8,8), due_date # aug 8th    
-  
   end
   
   def test_yearly_pattern
@@ -206,10 +195,33 @@ class RecurringTodoTest &lt; Test::Rails::TestCase
   end
 
   def test_start_from_in_future
+    # every_day should return start_day if it is in the future
+    @every_day.start_from = @in_three_days
+    due_date = @every_day.get_due_date(nil)
+    assert_equal @in_three_days, due_date
+    due_date = @every_day.get_due_date(@tomorrow)
+    assert_equal @in_three_days, due_date
+    
+    # if we give a date in the future for the previous todo, the next to do
+    # should be based on that future date.
+    due_date = @every_day.get_due_date(@in_four_days)
+    assert_equal @in_four_days+1.day, due_date    
+
+    @weekly_every_day.start_from = Time.utc(2020,1,1)
+    assert_equal Time.utc(2020,1,1), @weekly_every_day.get_due_date(nil)
+    assert_equal Time.utc(2020,1,1), @weekly_every_day.get_due_date(Time.utc(2019,10,1))
+    assert_equal Time.utc(2020,1,10), @weekly_every_day.get_due_date(Time.utc(2020,1,9))
+
+    @monthly_every_last_friday.start_from = Time.utc(2020,1,1)
+    assert_equal Time.utc(2020,1,31), @monthly_every_last_friday.get_due_date(nil) # last friday of jan
+    assert_equal Time.utc(2020,1,31), @monthly_every_last_friday.get_due_date(Time.utc(2019,12,1)) # last friday of jan
+    assert_equal Time.utc(2020,2,28), @monthly_every_last_friday.get_due_date(Time.utc(2020,2,1)) # last friday of feb
+
     # start from after june 8th 2008
-    @yearly.start_from = Time.utc(2008,6,12)
-    assert_equal Time.utc(2009,6,8), @yearly.get_due_date(nil) # jun 8th next year
-    assert_equal Time.utc(2009,6,8), @yearly.get_due_date(Time.utc(2008,6,1)) # also next year
+    @yearly.start_from = Time.utc(2020,6,12)
+    assert_equal Time.utc(2021,6,8), @yearly.get_due_date(nil) # jun 8th next year
+    assert_equal Time.utc(2021,6,8), @yearly.get_due_date(Time.utc(2019,6,1)) # also next year
+    assert_equal Time.utc(2021,6,8), @yearly.get_due_date(Time.utc(2020,6,15)) # also next year
     
     this_year = Time.now.utc.year
     @yearly.start_from = Time.utc(this_year+1,6,12)</diff>
      <filename>test/unit/recurring_todo_test.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>f4378ffde1b2364bbcbf999191a76f580fa02904</id>
    </parent>
  </parents>
  <author>
    <name>Reinier Balt</name>
    <email>lrbalt@gmail.com</email>
  </author>
  <url>http://github.com/bsag/tracks/commit/88ea02d29a44c51031e7e45eb4b4d3729646b5d5</url>
  <id>88ea02d29a44c51031e7e45eb4b4d3729646b5d5</id>
  <committed-date>2008-08-19T13:04:53-07:00</committed-date>
  <authored-date>2008-08-19T13:04:53-07:00</authored-date>
  <message>fix case with future start_from for other recurrence periods too

this patch belongs to previous</message>
  <tree>d19322be8eef4a8fa4dd236e305bf06159ae2e15</tree>
  <committer>
    <name>Reinier Balt</name>
    <email>lrbalt@gmail.com</email>
  </committer>
</commit>
