Module: RichUnits::Times::Time

Included in:
Time
Defined in:
lib/richunits/times.rb

Overview

Time Extensions

Instance Method Summary collapse

Instance Method Details

#ago(number, units = :seconds) ⇒ Object

Returns a new Time representing the time a number of time-units ago.



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
# File 'lib/richunits/times.rb', line 67

def ago(number, units=:seconds)
  time =(
    case units.to_s.downcase.to_sym
    when :years
      set(:year => (year - number))
    when :months
      #years = ((month - number) / 12).to_i
      y = ((month - number) / 12).to_i
      m = ((month - number - 1) % 12) + 1
      set(:year => (year - y), :month => m)
    when :weeks
      self - (number * 604800)
    when :days
      self - (number * 86400)
    when :hours
      self - (number * 3600)
    when :minutes
      self - (number * 60)
    when :seconds, nil
      self - number
    else
      raise ArgumentError, "unrecognized time units -- #{units}"
    end
  )
  dst_adjustment(time)
end

#beginning_of_dayObject Also known as: midnight, at_midnight, at_beginning_of_day, start_of_day

Returns a new Time representing the start of the day (0:00)



330
331
332
# File 'lib/richunits/times.rb', line 330

def beginning_of_day
  self - self.seconds_since_midnight
end

#beginning_of_monthObject Also known as: at_beginning_of_month

Returns a new Time representing the start of the month (1st of the month, 0:00)



340
341
342
343
# File 'lib/richunits/times.rb', line 340

def beginning_of_month
  #self - ((self.mday-1).days + self.seconds_since_midnight)
  change(:day => 1,:hour => 0, :min => 0, :sec => 0, :usec => 0)
end

#beginning_of_weekObject Also known as: monday, at_beginning_of_week

Returns a new Time representing the “start” of this week (Monday, 0:00)



309
310
311
# File 'lib/richunits/times.rb', line 309

def beginning_of_week
  (self - self.wday.days).midnight + 1.day
end

#beginning_of_yearObject Also known as: at_beginning_of_year

Returns a new Time representing the start of the year (1st of january, 0:00)



347
348
349
# File 'lib/richunits/times.rb', line 347

def beginning_of_year
  change(:month => 1,:day => 1,:hour => 0, :min => 0, :sec => 0, :usec => 0)
end

#change(options) ⇒ Object

Returns a new Time where one or more of the elements have been changed according to the options parameter. The time options (hour, minute, sec, usec) reset cascadingly, so if only the hour is passed, then minute, sec, and usec is set to 0. If the hour and minute is passed, then sec and usec is set to 0.

t = Time.now            #=> Sat Dec 01 14:10:15 -0500 2007
t.change(:hour => 11)   #=> Sat Dec 01 11:00:00 -0500 2007


50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/richunits/times.rb', line 50

def change(options)
  opts=options; #{}; options.each_pair{ |k,v| opts[k] = v.to_i }
  self.class.send(
    self.utc? ? :utc : :local,
    opts[:year]  || self.year,
    opts[:month] || self.month,
    opts[:day]   || self.day,
    opts[:hour]  || self.hour,
    opts[:min]   || (opts[:hour] ? 0 : self.min),
    opts[:sec]   || ((opts[:hour] || opts[:min]) ? 0 : self.sec),
    opts[:usec]  || ((opts[:hour] || opts[:min] || opts[:sec]) ? 0 : self.usec)
  )
end

#days_ago(days) ⇒ Object

Returns a new Time representing the time a number of days ago.



180
181
182
# File 'lib/richunits/times.rb', line 180

def days_ago(days)
  self - (days * 86400)
end

#days_hence(days) ⇒ Object Also known as: days_since

Returns a new Time representing the time a number of days hence.



239
240
241
# File 'lib/richunits/times.rb', line 239

def days_hence(days)
  self + (days * 86400)
end

#dst_adjustment(time) ⇒ Object

Adjust DST

TODO: Can’t seem to get this to pass ActiveSupport tests.

Even though it is essentially identical to the
ActiveSupport code (see Time#since in time/calculations.rb).
It handels all but 4 tests.


138
139
140
141
142
143
144
145
146
147
# File 'lib/richunits/times.rb', line 138

def dst_adjustment(time)
  self_dst = self.dst? ? 1 : 0
  time_dst = time.dst? ? 1 : 0
  seconds  = (self - time).abs
  if (seconds >= 86400 && self_dst != time_dst)
    time + ((self_dst - time_dst) * 60 * 60)
  else
    time
  end
end

#end_of_dayObject Also known as: to_end_of_day

Returns a new time at end of day



371
372
373
# File 'lib/richunits/times.rb', line 371

def end_of_day
  Time.mktime(year, month, day, 23, 59, 59, 999)
end

#hence(number, units = :seconds) ⇒ Object Also known as: in, since, from_now

Returns a new Time representing the time a number of time-units hence.



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/richunits/times.rb', line 98

def hence(number, units=:seconds)
  time =(
    case units.to_s.downcase.to_sym
    when :years
      set( :year=>(year + number) )
    when :months
      y = ((month + number) / 12).to_i
      m = ((month + number - 1) % 12) + 1
      set(:year => (year + y), :month => m)
    when :weeks
      self + (number * 604800)
    when :days
      self + (number * 86400)
    when :hours
      self + (number * 3600)
    when :minutes
      self + (number * 60)
    when :seconds
      self + number
    else
      raise ArgumentError, "unrecognized time units -- #{units}"
    end
  )
  dst_adjustment(time)
end

#hours_ago(hours) ⇒ Object

Returns a new Time representing the time a number of hours ago.



173
174
175
# File 'lib/richunits/times.rb', line 173

def hours_ago(hours)
  self - (hours * 3600)
end

#hours_hence(hours) ⇒ Object

Returns a new Time representing the time a number of hours hence.



232
233
234
# File 'lib/richunits/times.rb', line 232

def hours_hence(hours)
  self + (hours * 3600)
end

#in_day_range?(stime = ZERO, etime = NEVER) ⇒ Boolean

Returns true only if day of time is included in the range (stime..etime). Only year days are checked.

Returns:

  • (Boolean)


378
379
380
381
382
383
384
385
386
387
388
# File 'lib/richunits/times.rb', line 378

def in_day_range?(stime=ZERO, etime=NEVER)
  if (etime <= stime)
    warn "invalid end time (#{etime} < #{stime})" if $DEBUG
    etime = NEVER
  end

  stime = stime.to_start_of_day
  etime = etime.to_end_of_day

  return (stime..etime).include?(time)
end

#last_monthObject

Short-hand for months_ago(1)



299
300
301
# File 'lib/richunits/times.rb', line 299

def last_month
  months_ago(1)
end

#last_yearObject

Short-hand for years_ago(1)



289
290
291
# File 'lib/richunits/times.rb', line 289

def last_year
  years_ago(1)
end

#minutes_ago(minutes) ⇒ Object

Returns a new Time representing the time a number of minutes ago.



166
167
168
# File 'lib/richunits/times.rb', line 166

def minutes_ago(minutes)
  self - (minutes * 60)
end

#minutes_hence(minutes) ⇒ Object Also known as: minutes_since

Returns a new Time representing the time a number of minutes hence.



225
226
227
# File 'lib/richunits/times.rb', line 225

def minutes_hence(minutes)
  self + (minutes * 60)
end

#months_ago(months) ⇒ Object

Returns a new Time representing the time a number of months ago.



194
195
196
197
# File 'lib/richunits/times.rb', line 194

def months_ago(months)
  years = (month - months / 12).to_i
  set(:year=>(year - years), :month=>(month - months) % 12)
end

#months_hence(months) ⇒ Object Also known as: months_since

Returns a new Time representing the time a number of months hence.



253
254
255
256
# File 'lib/richunits/times.rb', line 253

def months_hence(months)
  years = (month + months / 12).to_i
  set(:year=>(year + years), :month=>(month + months) % 12)
end

#next_monthObject

Short-hand for months_since(1)



304
305
306
# File 'lib/richunits/times.rb', line 304

def next_month
  months_since(1)
end

#next_week(day = :monday) ⇒ Object

Returns a new Time representing the start of the given day in next week (default is Monday).



317
318
319
320
321
322
# File 'lib/richunits/times.rb', line 317

def next_week(day = :monday)
  days_into_week = { :monday => 0, :tuesday => 1, :wednesday => 2,
                     :thursday => 3, :friday => 4, :saturday => 5,
                     :sunday => 6 }
  since(1.week).beginning_of_week.since(days_into_week[day].day).change(:hour => 0)
end

#next_yearObject

Short-hand for years_since(1)



294
295
296
# File 'lib/richunits/times.rb', line 294

def next_year
  years_since(1)
end

#seconds_since_midnightObject

Seconds since midnight: Time.now.seconds_since_midnight



151
152
153
# File 'lib/richunits/times.rb', line 151

def seconds_since_midnight
  self.hour.hours + self.min.minutes + self.sec + (self.usec/1.0e+6)
end

#set(options) ⇒ Object

Like change but does not reset earlier times.

NOTE: It would be better, probably if this were called “change”.

and that #change were called "reset".


27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/richunits/times.rb', line 27

def set(options)
  opts={}; options.each_pair{ |k,v| opts[k] = v.to_i }
  self.class.send( self.utc? ? :utc : :local,
    opts[:year]  || self.year,
    opts[:month] || self.month,
    opts[:day]   || self.day,
    opts[:hour]  || self.hour,
    opts[:min]   || self.min,
    opts[:sec]   || self.sec,
    opts[:usec]  || self.usec
  )
end

#tomorrowObject

Convenience method which returns a new Time representing the time 1 day since the instance time



360
361
362
# File 'lib/richunits/times.rb', line 360

def tomorrow
  self.since(1.day)
end

#weeks_ago(weeks) ⇒ Object

Returns a new Time representing the time a number of weeks ago.



187
188
189
# File 'lib/richunits/times.rb', line 187

def weeks_ago(weeks)
  self - (weeks * 604800)
end

#weeks_hence(weeks) ⇒ Object Also known as: weeks_since

Returns a new Time representing the time a number of weeks hence.



246
247
248
# File 'lib/richunits/times.rb', line 246

def weeks_hence(weeks)
  self + (weeks * 604800)
end

#years_ago(years) ⇒ Object

Returns a new Time representing the time a number of years ago.



212
213
214
# File 'lib/richunits/times.rb', line 212

def years_ago(years)
  set(:year=>(year - years))
end

#years_hence(years) ⇒ Object Also known as: years_since

Returns a new Time representing the time a number of years hence.



269
270
271
# File 'lib/richunits/times.rb', line 269

def years_hence(years)
  set(:year=>(year + years))
end

#yesterdayObject

Convenience method which returns a new Time representing the time 1 day ago



354
355
356
# File 'lib/richunits/times.rb', line 354

def yesterday
  self.ago(1.day)
end