class Moments::Difference

Calculates differences between two given Time instances.

Constants

DATE_PARTS
TIME_CLASSES
TIME_PARTS

Public Class Methods

new(from, to) click to toggle source

Parameters:

from

A instance of Time

to

A instance of Time

# File lib/moments/difference.rb, line 27
def initialize(from, to)
  @from = parse_argument from
  @to = parse_argument to

  @ordered_from, @ordered_to = [@from, @to].sort

  precise_difference
end

Public Instance Methods

future?() click to toggle source
# File lib/moments/difference.rb, line 40
def future?
  @from < @to
end
in_days() click to toggle source
# File lib/moments/difference.rb, line 64
def in_days
  in_hours / 24
end
in_hours() click to toggle source
# File lib/moments/difference.rb, line 60
def in_hours
  in_minutes / 60
end
in_minutes() click to toggle source
# File lib/moments/difference.rb, line 56
def in_minutes
  in_seconds / 60
end
in_months() click to toggle source
# File lib/moments/difference.rb, line 68
def in_months
  months_diff = @ordered_to.month - @ordered_from.month
  months_diff -= 1 if months_diff.positive? && @ordered_to.mday < @ordered_from.mday

  (@ordered_to.year - @ordered_from.year) * 12 + months_diff
end
in_seconds() click to toggle source
# File lib/moments/difference.rb, line 52
def in_seconds
  @ordered_to.to_i - @ordered_from.to_i
end
in_years() click to toggle source
# File lib/moments/difference.rb, line 75
def in_years
  years_diff = @ordered_to.year - @ordered_from.year

  return years_diff unless years_diff.positive?
  return years_diff if @ordered_to.month > @ordered_from.month

  if (@ordered_to.month < @ordered_from.month) || (@ordered_to.mday < @ordered_from.mday)
    years_diff -= 1
  end

  years_diff
end
past?() click to toggle source
# File lib/moments/difference.rb, line 48
def past?
  @from > @to
end
same?() click to toggle source
# File lib/moments/difference.rb, line 44
def same?
  @from == @to
end
to_hash() click to toggle source
# File lib/moments/difference.rb, line 36
def to_hash
  @diff
end

Private Instance Methods

calculate(attribute, difference, stepping = 60) click to toggle source
# File lib/moments/difference.rb, line 128
def calculate(attribute, difference, stepping = 60)
  return unless @diff.key?(attribute) && @diff.key?(difference)

  return if @diff[attribute] >= 0

  @diff[attribute] += stepping
  @diff[difference] -= 1
end
calculate_days() click to toggle source
# File lib/moments/difference.rb, line 137
def calculate_days
  return if @diff[:days] >= 0

  previous_month_days = (Time.new(@to.year, @to.month, 1) - 1).day
  @diff[:days] = precise_previous_month_days(
    @diff[:days], previous_month_days, @from.day
  )
  @diff[:months] -= 1
end
calculate_diff() click to toggle source
# File lib/moments/difference.rb, line 117
def calculate_diff
  are_time_parts = [@from, @to].all? do |value|
    TIME_CLASSES.any? { |time_class| value.is_a?(time_class) }
  end

  (are_time_parts ? DATE_PARTS.merge(TIME_PARTS) : DATE_PARTS)
    .transform_values do |method_name|
      @ordered_to.public_send(method_name) - @ordered_from.public_send(method_name)
    end
end
parse_argument(value) click to toggle source
# File lib/moments/difference.rb, line 94
def parse_argument(value)
  case value
  when *TIME_CLASSES
    value.to_time.getutc
  when Date
    value
  else
    raise ArgumentError, 'Unsupported format'
  end
end
precise_difference() click to toggle source
# File lib/moments/difference.rb, line 105
def precise_difference
  @diff = calculate_diff

  calculate :seconds, :minutes
  calculate :minutes, :hours
  calculate :hours, :days, 24
  calculate_days
  calculate :months, :years, 12

  @diff
end
precise_previous_month_days(days, previous, from) click to toggle source
# File lib/moments/difference.rb, line 147
def precise_previous_month_days(days, previous, from)
  if previous < from
    previous + days + (from - previous)
  else
    previous + days
  end
end