class Mhc::PropertyValue::Date

Constants

DAYS_OF_MONTH

Public Class Methods

new_by_day(year, month, nth, wday) click to toggle source

Make a date by DAY like “1st Wed of Nov, 1999''. caller must make sure:

YEAR and MONTH must be valid.
NTH must be <0 or >0.
WDAY must be 0..6.

returns nil if no date was match (for example, no 5th Saturday exists on April 2010).

# File lib/mhc/property_value/date.rb, line 156
def self.new_by_day(year, month, nth, wday)
  return nil if nth < -5 or nth > 5 or nth == 0
  direction = nth > 0 ? 1 : -1

  edge      = Date.new(year, month, direction)
  y_offset  = nth - direction
  x_offset  = wday_difference(edge.wday, wday, direction)
  mday      = edge.mday + y_offset * 7 + x_offset

  return new(year, month, mday) # May raise ArgumentError
end
parse(string, default = nil) click to toggle source
# File lib/mhc/property_value/date.rb, line 10
def self.parse(string, default = nil)
  begin
    # YYYYMMDD/HH:MM => DateTime
    if /^(\d{4})(\d{2})(\d{2})\/(\d{2}):(\d{2})$/ =~ string
      DateTime.new($1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, 0)

    # YYYYMMDD => Date
    elsif /^(\d{4})(\d{2})(\d{2})$/ =~ string
      Date.new($1.to_i, $2.to_i, $3.to_i)

    # YYYYMMDD/hh:mm-HH:MM => DateTime taking YYYYMMDD, HH:MM
    elsif /^(\d+):(\d+)$/ =~ string && default
      DateTime.new(default.year, default.month, default.day, $1.to_i, $2.to_i, 0)

    else
      fail ParseError
    end
  rescue
    raise ParseError, "invalid date string \"#{string}\""
  end
end
parse_range(range_string) click to toggle source
# File lib/mhc/property_value/date.rb, line 57
def self.parse_range(range_string)
  case range_string
  # all
  when /^all$/
    return self.parse("19700101")..self.today + 365*10 # 10 years ahead

  # yyyymmdd-yyyymmdd
  when /^([^+-]+)-([^+-]+)$/
    return parse_relative($1)..parse_relative($2)

  # yyyymmdd+2w
  when /^([^+-]+)\+(\d+)([dwm])$/
    date = parse_relative($1)
    return date..date.succ_by($3, $2.to_i).prev_day

  when /^(thismonth|nextmonth|\d{6})$/
    date = parse_relative($1)
    return date..date.last_day_of_month

  when /^([^+-]+)$/
    date = parse_relative($1)
    return date..date
  else
    raise ParseError, "invalid date range string \"#{range_string}\""
  end
end
parse_relative(date_string) click to toggle source
# File lib/mhc/property_value/date.rb, line 32
def self.parse_relative(date_string)
  case (date_string.downcase)
  when 'today'
    return self.today

  when 'tomorrow'
    return self.today.succ

  when /^\d{8}$/
    return self.parse(date_string)

  when /^\d{6}$/
    return self.parse(date_string + '01')

  when /^thismonth$/
    return self.today.first_day_of_month

  when /^nextmonth$/
    return self.today.first_day_of_month.next_month

  else
    raise ParseError, "invalid date string \"#{date_string}\""
  end
end

Public Instance Methods

absolute_from_epoch() click to toggle source
# File lib/mhc/property_value/date.rb, line 142
def absolute_from_epoch
  return (self - Date.new(1970, 1, 1)).to_i
end
add_time(time = nil) click to toggle source
# File lib/mhc/property_value/date.rb, line 99
def add_time(time = nil)
  if time
    return ::Time.local(year, month, mday, time.hour, time.minute)
  else
    return ::Time.local(year, month, mday, 0, 0)
  end
end
days_of_month() click to toggle source
# File lib/mhc/property_value/date.rb, line 120
def days_of_month
  return DAYS_OF_MONTH[month] + (month == 2 && leap? ? 1 : 0)
end
each_day_in_month() { |class.new(year, month, d)| ... } click to toggle source
# File lib/mhc/property_value/date.rb, line 132
def each_day_in_month
  for d in (1 .. days_of_month)
    yield self.class.new(year, month, d)
  end
end
first_day_of_month() click to toggle source
# File lib/mhc/property_value/date.rb, line 124
def first_day_of_month
  return self.class.new(year, month, 1)
end
last_day_of_month() click to toggle source
# File lib/mhc/property_value/date.rb, line 128
def last_day_of_month
  return self.class.new(year, month, -1)
end
last_week_of_month?() click to toggle source
# File lib/mhc/property_value/date.rb, line 112
def last_week_of_month?
  return mday > days_of_month - 7
end
next_day(month, nth, wday) click to toggle source
# File lib/mhc/property_value/date.rb, line 173
def next_day(month, nth, wday)
  year = self.year + (month < self.month ? 1 : 0)
  year += 1 while !(date = self.class.new_by_day(year, month, nth, wday))
  return date
end
next_monthday(month, mday) click to toggle source
# File lib/mhc/property_value/date.rb, line 168
def next_monthday(month, mday)
  year = self.year + (month < self.month ? 1 : 0)
  return self.class.new(year, month, mday)
end
parse(string, default = nil) click to toggle source
# File lib/mhc/property_value/date.rb, line 95
def parse(string, default = nil)
  self.class.parse(string, default)
end
succ_by(unit = :d, number = 1) click to toggle source
# File lib/mhc/property_value/date.rb, line 84
def succ_by(unit = :d, number = 1)
  case unit.to_sym
  when :d
    return self + number.to_i
  when :w
    return self + (number.to_i * 7)
  when :m
    return self >> number.to_i
  end
end
to_ics() click to toggle source
# File lib/mhc/property_value/date.rb, line 179
def to_ics
  return strftime("%Y%m%d")
end
to_mhc_string() click to toggle source
# File lib/mhc/property_value/date.rb, line 107
def to_mhc_string
  return strftime("%Y%m%d")
end
Also aliased as: to_s
to_s()
Alias for: to_mhc_string
today?() click to toggle source
# File lib/mhc/property_value/date.rb, line 138
def today?
  return self.class.today == self
end
week_number_of_month() click to toggle source
# File lib/mhc/property_value/date.rb, line 116
def week_number_of_month
  return (mday - 1) / 7 + 1
end

Private Instance Methods

wday_difference(from, to, direction) click to toggle source

Returns diff of days between 2 wdays: FROM and TO. Each FROM and TO is one of 0(=Sun) … 6(Sat).

DIRECTION must be -1 or 1, which represents search direction.

Sun Mon Tue Wed Thu Fri Sat Sun Mon Tue ...
 0   1   2   3   4   5   6   0   1   2  ...

returns 3 if FROM, TO, DIRECTION = 4, 0, 1 returns -4 if FROM, TO, DIRECTION = 4, 0, -1

# File lib/mhc/property_value/date.rb, line 196
def wday_difference(from, to, direction)
  return direction * ((direction * (to - from)) % 7)
end