Class: Temporal::Shift

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/temporal/shift.rb

Constant Summary collapse

MINUTE =
60
HOUR =
MINUTE * 60
DAY =
HOUR * 24
WEEK =
DAY * 7
YEAR =
12
MAX_MONTH_DAY =

Don’t worry about February

%w|31 0 31 30 31 30 31 31 30 31 30 31|.map{|n|n.to_i}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(amount, unit) ⇒ Shift

Returns a new instance of Shift.



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/temporal/shift.rb', line 18

def initialize amount, unit
  unless self.class.unit?( unit )
    raise Temporal::Anomaly.new( "Bad #{self.class}.unit type of `#{unit}' given" )
  end

  @seconds = 0
  @months = 0

  unit = unit.to_s.downcase
  unit.chop! if unit[-1..-1] == 's'
  unit = unit.to_sym

  case unit
  when :second
    @seconds = amount
  when :minute
    @seconds = amount * MINUTE
  when :hour
    @seconds = amount * HOUR
  when :day
    @seconds = amount * DAY
  when :week
    @seconds = amount * WEEK
  when :month
    @months = amount
  when :year
    @months = amount * YEAR
  else
    raise Temporal::Anomaly.new( "Internal Error, failed to catch bad #{self.class}.unit type of `#{unit}' given" )
  end
end

Instance Attribute Details

#monthsObject

Returns the value of attribute months.



16
17
18
# File 'lib/temporal/shift.rb', line 16

def months
  @months
end

#secondsObject

Returns the value of attribute seconds.



15
16
17
# File 'lib/temporal/shift.rb', line 15

def seconds
  @seconds
end

Class Method Details

.unit?(unit) ⇒ Boolean

Returns:

  • (Boolean)


62
63
64
# File 'lib/temporal/shift.rb', line 62

def self.unit? unit
  (unit.to_s.strip.downcase =~ /^(#{units.join('|')})s?$/) != nil
end

.unitsObject



58
59
60
# File 'lib/temporal/shift.rb', line 58

def self.units
  %w|second minute hour day week month year|
end

Instance Method Details

#+(to_be_added) ⇒ Object

Raises:



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/temporal/shift.rb', line 66

def + to_be_added

  if to_be_added.class == self.class
    result_instance = self.class.new( @seconds + to_be_added.seconds, :seconds )
    result_instance.months = @months + to_be_added.months
    return result_instance
  end

  if to_be_added.class == Time
    new_time = (to_be_added + @seconds).localtime
    new_year = new_time.year+(((new_time.month-1)+months)/12)
    new_month = (((new_time.month-1)+months)%12)
    new_day = new_time.day
    if new_month == 1
      if (new_year%4 == 0 and new_year%100 != 0) or new_year%400 == 0
        max_mday = 29
      else
        max_mday = 28
      end
    else
      max_mday = MAX_MONTH_DAY[ new_month ];
    end
    new_day = max_mday if new_day > max_mday
    return Time.local( new_year, new_month+1 , new_day, new_time.hour, new_time.min, new_time.sec, new_time.usec )
  end

  if to_be_added.class == Range
    new_first = self + to_be_added.first
    new_last = self + to_be_added.last
    if to_be_added.exclude_end?
      return new_first...new_last
    else
      return new_first..new_last
    end
  end

  raise Temporal::Anomaly.new( "Unable to add #{self.class} to instances of `#{to_be_added.class}'" )
end

#-(to_be_subtracted) ⇒ Object



111
112
113
114
115
116
117
# File 'lib/temporal/shift.rb', line 111

def - to_be_subtracted
  begin
    self + ( -to_be_subtracted )
  rescue Exception => e
    raise Temporal::Anomaly.new( "Unable to subtract an instance of #{to_be_subtracted.class} from #{self.class}" )
  end
end

#-@Object



105
106
107
108
109
# File 'lib/temporal/shift.rb', line 105

def -@
  negated = self.class.new( -@seconds, :seconds )
  negated.months = -@months
  return negated
end

#<=>(target) ⇒ Object



50
51
52
53
54
55
56
# File 'lib/temporal/shift.rb', line 50

def <=> target
  return 1 if @months > target.months
  return -1 if @months < target.months
  return 1 if @seconds > target.seconds
  return -1 if @seconds < target.seconds
  0
end

#to_sObject



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/temporal/shift.rb', line 119

def to_s
  result = {}

  result[:months] = @months

  result[:years] = (result[:months]/12).truncate
  result[:months] = result[:months] - ( result[:years] * 12 )
  result[:months] = result[:months].truncate if result[:months].modulo(1) == 0

  result[:seconds] = @seconds

  result[:weeks] = (result[:seconds] / WEEK).truncate
  result[:seconds] = result[:seconds] - (result[:weeks] * WEEK)
  result[:days] = (result[:seconds] / DAY).truncate
  result[:seconds] = result[:seconds] - (result[:days] * DAY)
  result[:hours] = (result[:seconds] / HOUR).truncate
  result[:seconds] = result[:seconds] - (result[:hours] * HOUR)
  result[:minutes] = (result[:seconds] / MINUTE).truncate
  result[:seconds] = result[:seconds] - (result[:minutes] * MINUTE)
  result[:seconds] = result[:seconds].truncate if result[:seconds].modulo(1) == 0

  result = Hash[ *result.select{|unit, amount| amount != 0 }.flatten ]

  string = ""

  %w|years months weeks days hours minutes seconds|.each do |unit|
    unit = unit.to_sym
    next unless result.has_key?( unit )
    string += "#{result[ unit ]} #{unit}"
    string.chop! if result[ unit ].abs == 1
    result.delete( unit )
    break if result.size == 0
    if result.size == 1
      string += " and "
    else
      string += ", "
    end
  end

  string
end