Permalink
Browse files

Namespace TimeUtil under IceCube

  • Loading branch information...
1 parent 3b3bb69 commit cbecb97c763899295ed33e157d77cd268d98aced John Crepezzi committed Aug 25, 2010
Showing with 85 additions and 78 deletions.
  1. +80 −76 lib/ice_cube/time_util.rb
  2. +4 −1 lib/ice_cube/validations/day_of_week.rb
  3. +1 −1 lib/ice_cube/version.rb
View
@@ -1,89 +1,93 @@
-module TimeUtil
-
- LeapYearMonthDays = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
- CommonYearMonthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
+module IceCube
- # this method exists because ActiveSupport will serialize
- # TimeWithZone's in collections in UTC time instead of
- # their local time. if +time+ is a TimeWithZone, we move
- # it to a DateTime
- # Note: When converting to datetime, you microseconds get set to 0
- def self.serializable_time(time)
- if time.respond_to?(:to_datetime)
- time.to_datetime
- else
- time
+ module TimeUtil
+
+ LeapYearMonthDays = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
+ CommonYearMonthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
+
+ # this method exists because ActiveSupport will serialize
+ # TimeWithZone's in collections in UTC time instead of
+ # their local time. if +time+ is a TimeWithZone, we move
+ # it to a DateTime
+ # Note: When converting to datetime, you microseconds get set to 0
+ def self.serializable_time(time)
+ if time.respond_to?(:to_datetime)
+ time.to_datetime
+ else
+ time
+ end
end
- end
-
- # TODO can we improve this more?
- def self.date_in_n_months(date, month_distance)
-
- next_mark = date
- days_in_month_of_next_mark = days_in_month(next_mark)
-
- month_distance.times do
+
+ # TODO can we improve this more?
+ def self.date_in_n_months(date, month_distance)
- prev_mark = next_mark
- next_mark += days_in_month_of_next_mark * ONE_DAY
+ next_mark = date
+ days_in_month_of_next_mark = days_in_month(next_mark)
- # only moving one day at a time, so this suffices
- months_covered = next_mark.month - prev_mark.month
- months_covered += 12 if months_covered < 0
-
- # step back to the end of the previous month of months_covered went too far
- if months_covered == 2
- next_mark -= next_mark.mday * ONE_DAY
+ month_distance.times do
+
+ prev_mark = next_mark
+ next_mark += days_in_month_of_next_mark * IceCube::ONE_DAY
+
+ # only moving one day at a time, so this suffices
+ months_covered = next_mark.month - prev_mark.month
+ months_covered += 12 if months_covered < 0
+
+ # step back to the end of the previous month of months_covered went too far
+ if months_covered == 2
+ next_mark -= next_mark.mday * IceCube::ONE_DAY
+ end
+
+ days_in_month_of_next_mark = days_in_month(next_mark)
+ next_mark = adjust(next_mark, prev_mark)
+
+ end
+
+ # at the end, there's a chance we're not on the correct day,
+ # but if we're not - we will always be behind it in the correct month
+ # if there exists no proper day in the month for us, return nil - otherwise, return that date
+
+ if days_in_month_of_next_mark >= date.mday
+ next_mark += (date.mday - next_mark.mday) * IceCube::ONE_DAY
end
-
- days_in_month_of_next_mark = days_in_month(next_mark)
- next_mark = adjust(next_mark, prev_mark)
end
-
- # at the end, there's a chance we're not on the correct day,
- # but if we're not - we will always be behind it in the correct month
- # if there exists no proper day in the month for us, return nil - otherwise, return that date
-
- if days_in_month_of_next_mark >= date.mday
- next_mark += (date.mday - next_mark.mday) * ONE_DAY
+
+ def adjust(goal, date)
+ return goal if goal.utc_offset == date.utc_offset
+ goal - goal.utc_offset + date.utc_offset
end
- end
-
- def adjust(goal, date)
- return goal if goal.utc_offset == date.utc_offset
- goal - goal.utc_offset + date.utc_offset
- end
-
- def self.is_leap?(year)
- (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)
- end
-
- def self.days_in_year(date)
- is_leap?(date.year) ? 366 : 365
- end
-
- def self.days_in_month(date)
- is_leap?(date.year) ? LeapYearMonthDays[date.month - 1] : CommonYearMonthDays[date.month - 1]
- end
-
- def self.ical_format(time)
- if time.utc?
- ":#{time.strftime('%Y%m%dT%H%M%SZ')}" # utc time
- else
- ";TZID=#{time.strftime('%Z:%Y%m%dT%H%M%S')}" # local time specified
+ def self.is_leap?(year)
+ (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)
+ end
+
+ def self.days_in_year(date)
+ is_leap?(date.year) ? 366 : 365
end
+
+ def self.days_in_month(date)
+ is_leap?(date.year) ? LeapYearMonthDays[date.month - 1] : CommonYearMonthDays[date.month - 1]
+ end
+
+ def self.ical_format(time)
+ if time.utc?
+ ":#{time.strftime('%Y%m%dT%H%M%SZ')}" # utc time
+ else
+ ";TZID=#{time.strftime('%Z:%Y%m%dT%H%M%S')}" # local time specified
+ end
+ end
+
+ def self.ical_duration(duration)
+ hours = duration / 3600; duration %= 3600
+ minutes = duration / 60; duration %= 60
+ repr = ''
+ repr << "#{hours}H" if hours > 0
+ repr << "#{minutes}M" if minutes > 0
+ repr << "#{duration}S" if duration > 0
+ "PT#{repr}"
+ end
+
end
- def self.ical_duration(duration)
- hours = duration / 3600; duration %= 3600
- minutes = duration / 60; duration %= 60
- repr = ''
- repr << "#{hours}H" if hours > 0
- repr << "#{minutes}M" if minutes > 0
- repr << "#{duration}S" if duration > 0
- "PT#{repr}"
- end
-
end
@@ -18,7 +18,10 @@ def validate(date)
@days_of_week[date.wday].include?(nth_occurrence_of_weekday) || @days_of_week[date.wday].include?(nth_occurrence_of_weekday - this_weekday_in_month_count - 1)
end
- #note - temporary implementation
+
+ # note - temporary implementation
+ # instead - once we know what weekday starts the month, we should be able to figure out
+ # the rest with basic math
def closest(date)
return nil if !@days_of_week || @days_of_week.empty?
goal = date
View
@@ -1,5 +1,5 @@
module IceCube
- VERSION = '0.5.1'
+ VERSION = '0.5.2'
end

0 comments on commit cbecb97

Please sign in to comment.