Skip to content

Instantly share code, notes, and snippets.

@leikind
Created February 15, 2011 15:08
Show Gist options
  • Save leikind/827624 to your computer and use it in GitHub Desktop.
Save leikind/827624 to your computer and use it in GitHub Desktop.
optimizing some calendar logic
require 'rubygems'
require 'activesupport'
class Contract
attr_reader :start_date, :renew_date
def initialize(start_date, renew_date)
@start_date, @renew_date = start_date, renew_date
end
def nth_year(n)
[self.start_date.advance(:years => n - 1), self.start_date.advance(:years => n, :days => -1)]
end
def first_year
nth_year(1)
end
def second_year
nth_year(2)
end
def third_year
nth_year(3)
end
def each_year_up_to(up_to_date, n = 1)
start, _end = nth_year(n)
while start <= up_to_date
yield n, start, _end
n += 1
start, _end = nth_year(n)
end
end
def each_year
each_year_up_to(self.renew_date) do |n, start, _end|
yield n, start, _end
end
end
def inspect
res = "Contract #{start_date} -> #{renew_date}\n"
each_year do |n, start, _end|
res << "year #{n}) #{start} => #{_end}\n"
end
res
end
def which_year_inefficient(date)
return nil if date < start_date
each_year_up_to(date) do |n, start, _end|
if date >= start && date <= _end
return n
end
end
end
def which_year_efficient(date)
return nil if date < self.start_date
days_between = date - self.start_date
start_from_year = (days_between.to_f / 365).floor
each_year_up_to(date, start_from_year) do |n, start, _end|
if date >= start && date <= _end
return n
end
end
end
end
contract = Contract.new(Date.new(2011, 2, 3), Date.new(2014, 2, 3))
puts
p contract
puts
[
[2009, 10, 13],
[2011, 2, 3],
[2011, 10, 13],
[2012, 2, 2],
[2012, 2, 3],
[2012, 10, 10],
[2014, 2, 5],
[2024, 2, 5],
[2084, 2, 5],
[2090, 2, 2],
[2090, 2, 3]
].each do |date_data|
date = Date.new(*date_data)
puts
puts "algorythm 1: #{date} = year #{contract.which_year_inefficient(date)}"
puts "algorythm 2: #{date} = year #{contract.which_year_efficient(date)}"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment