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.



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

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)



362
363
364
# File 'lib/richunits/times.rb', line 362

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)



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

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)



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

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)



379
380
381
# File 'lib/richunits/times.rb', line 379

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


82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/richunits/times.rb', line 82

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.



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

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.



271
272
273
# File 'lib/richunits/times.rb', line 271

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.


170
171
172
173
174
175
176
177
178
179
# File 'lib/richunits/times.rb', line 170

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



403
404
405
# File 'lib/richunits/times.rb', line 403

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.



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

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.



205
206
207
# File 'lib/richunits/times.rb', line 205

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

#hours_hence(hours) ⇒ Object

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



264
265
266
# File 'lib/richunits/times.rb', line 264

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)


410
411
412
413
414
415
416
417
418
419
420
# File 'lib/richunits/times.rb', line 410

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)



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

def last_month
  months_ago(1)
end

#last_yearObject

Short-hand for years_ago(1)



321
322
323
# File 'lib/richunits/times.rb', line 321

def last_year
  years_ago(1)
end

#minutes_ago(minutes) ⇒ Object

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



198
199
200
# File 'lib/richunits/times.rb', line 198

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.



257
258
259
# File 'lib/richunits/times.rb', line 257

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

#months_ago(months) ⇒ Object

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



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

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.



285
286
287
288
# File 'lib/richunits/times.rb', line 285

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)



336
337
338
# File 'lib/richunits/times.rb', line 336

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).



349
350
351
352
353
354
# File 'lib/richunits/times.rb', line 349

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)



326
327
328
# File 'lib/richunits/times.rb', line 326

def next_year
  years_since(1)
end

#seconds_since_midnightObject

Seconds since midnight: Time.now.seconds_since_midnight



183
184
185
# File 'lib/richunits/times.rb', line 183

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".


59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/richunits/times.rb', line 59

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



392
393
394
# File 'lib/richunits/times.rb', line 392

def tomorrow
  self.since(1.day)
end

#weeks_ago(weeks) ⇒ Object

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



219
220
221
# File 'lib/richunits/times.rb', line 219

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.



278
279
280
# File 'lib/richunits/times.rb', line 278

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

#years_ago(years) ⇒ Object

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



244
245
246
# File 'lib/richunits/times.rb', line 244

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.



301
302
303
# File 'lib/richunits/times.rb', line 301

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

#yesterdayObject

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



386
387
388
# File 'lib/richunits/times.rb', line 386

def yesterday
  self.ago(1.day)
end