Class: Date

Inherits:
Object
  • Object
show all
Defined in:
lib/anniversary/date_additions.rb

Class Method Summary (collapse)

Instance Method Summary (collapse)

Class Method Details

+ (Object) civil_with_missing_day_correction(year, month, day)

Return a date with a given year, month and day. If the date would be invalid because that day does not exist in that month in that year, then return an equivalent date, 'reflected' around the end of the month. For example, Date.civil_with_missing_day_correction(2001, 2, 29) would return Date.civil(2001, 3, 1), and Date.civil_with_missing_day_correction(2011, 2, 31) would return Date.civil(2011, 3, 2)



17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/anniversary/date_additions.rb', line 17

def self.civil_with_missing_day_correction(year, month, day)
days_in_month = [
  #   J   F   M   A   M   J   J   A   S   O   N   D
  0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  ][month]
  days_in_month = 29 if (month == 2) && ((year % 4 == 0) && ((year % 400 == 0) || (year % 100 != 0)))
  if (days_in_month < day)
    month += 1
    day = day - days_in_month
  end
  civil(year, month, day)
end

Instance Method Details

- (Object) in_year_with_correction(yr, mth = month) Also known as: in_year_and_month_with_correction

Return the equivalent date in a different year and optionally month. If the result of just changing the year and or month results in an invalid date e.g. September 31 in any year, or February 29 in a non-leap year, then return a valid date in the next month, see Date.civil_with_missing_day_correction



8
9
10
# File 'lib/anniversary/date_additions.rb', line 8

def in_year_with_correction(yr,mth=month)
  Date.civil_with_missing_day_correction(yr, mth, day)
end

- (Object) years_months_days_since(initial_date, debug = false)

return a 3 element array comprising the number of years, months and days which have occurred between the argument initial_date and the receiver

:call-seq: years_months_days_since(initial_date)

The return values are

0. years - the number of anniversary dates which have occurred 
1. months - the number of 'monthiversary' dates which have occurred since the last anniversary date
2. days - the number of days since the last monthiversary

If the receiver is before the argument then years, months and days will be 0 or negative values.



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/anniversary/date_additions.rb', line 42

def years_months_days_since(initial_date, debug = false)
  if initial_date < self
    puts "#{self}.years_months_days_since(#{initial_date})" if debug
    anniversary_this_year = initial_date.in_year_with_correction(year)
    puts "anniversary_this_year is #{anniversary_this_year}" if debug
    years = if anniversary_this_year <= self
      year - initial_date.year
    else
      year - initial_date.year - 1
    end
    last_monthiversary = monthiversary_this_month = initial_date.in_year_and_month_with_correction(year, month)
    puts "monthiversary_this_month is #{monthiversary_this_month}" if debug
    if (monthiversary_this_month > self)
      last_month = Date.civil(year, month, 1) << 1
      last_monthiversary = initial_date.in_year_and_month_with_correction(last_month.year, last_month.month)
    end
    puts "last_monthiversary is #{last_monthiversary}" if debug

    if last_monthiversary > initial_date
      months = (last_monthiversary.month - anniversary_this_year.month)
      months += 12 if months < 0
    else
      months = 0
    end
    days = (self - last_monthiversary).to_i
  elsif initial_date > self
    initial_date.years_months_days_since(self, debug).map {|v| -v}
  else
    years, months, days = 0, 0, 0
  end

  [years, months, days]
end

- (Object) years_months_days_until(end_date, debug = false)

return a 3 element array comprising the number of years, months and days which will occur between the argument end_date and the receiver

:call-seq: years_months_days_until(end_date)

The return values are

0. years - the number of anniversary dates which will occur 
1. months - the number of 'monthiversary' dates which will occur after the last anniversary date
2. days - the number of days after the last monthiversary

If the receiver is after the argument then years, months and days will be 0 or negative values.



88
89
90
# File 'lib/anniversary/date_additions.rb', line 88

def years_months_days_until(end_date, debug = false)
  end_date.years_months_days_since(self)
end