Class: TaskJuggler::TjTime
Overview
The TjTime class extends the original Ruby class Time with lots of TaskJuggler specific additional functionality. This is mostly for handling time zones.
Constant Summary collapse
- MON_MAX =
The number of days per month. Leap years are taken care of separately.
[ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]
- @@tz =
Initialize @@tz with the current time zone if it is set.
Instance Attribute Summary collapse
-
#time ⇒ Object
readonly
Returns the value of attribute time.
Class Method Summary collapse
-
.checkTimeZone(zone) ⇒ Object
Check if
zone
is a valid time zone. -
.setTimeZone(zone) ⇒ Object
Set a new active time zone.
-
.timeZone ⇒ Object
Return the name of the currently active time zone.
Instance Method Summary collapse
-
#%(val) ⇒ Object
Convert the time to seconds since Epoch and return the module of val.
-
#+(secs) ⇒ Object
Add secs number of seconds to the time.
-
#-(arg) ⇒ Object
Substract arg number of seconds or return the number of seconds between arg and this time.
-
#<(t) ⇒ Object
Return true if time is smaller than t.
-
#<=(t) ⇒ Object
Return true if time is smaller or equal than t.
-
#<=>(t) ⇒ Object
Coparison operator for time with another time t.
-
#==(t) ⇒ Object
Return true if time and t are identical.
-
#>(t) ⇒ Object
Return true if time is larger than t.
-
#>=(t) ⇒ Object
Return true if time is larger or equal than t.
-
#align(clock) ⇒ Object
Align the date to a time grid.
-
#beginOfHour ⇒ Object
Normalize time to the beginning of the current hour.
-
#beginOfMonth ⇒ Object
Normalize time to the beginning of the current month.
-
#beginOfQuarter ⇒ Object
Normalize time to the beginning of the current quarter.
-
#beginOfWeek(startMonday) ⇒ Object
Normalize time to the beginning of the current week.
-
#beginOfYear ⇒ Object
Normalize time to the beginning of the current year.
-
#day ⇒ Object
Return the day of the month (1..n).
-
#daysTo(date) ⇒ Object
Return the number of days between this time and date.
-
#hour ⇒ Object
Return the hours of the day (0..23).
-
#hoursLater(hours) ⇒ Object
Return a new time that is hours later than time.
-
#hoursTo(date) ⇒ Object
Return the number of hours between this time and date.
-
#initialize(t = nil) ⇒ TjTime
constructor
call-seq: TjTime() -> TjTime (now) TjTime(tjtime) -> TjTime TjTime(time, timezone) -> TjTime TjTime(str) -> TjTime TjTime(secs) -> TjTime.
-
#midnight ⇒ Object
Normalize time to the beginning of the current day.
-
#month ⇒ Object
(also: #mon)
Return the month of the year (1..12).
-
#monthsTo(date) ⇒ Object
Return the number of months between this time and date.
-
#nextDayOfWeek(dow) ⇒ Object
Return the start of the next dow day of week after date.
-
#quartersTo(date) ⇒ Object
Return the number of quarters between this time and date.
-
#sameTimeNextDay ⇒ Object
Return a new time that is 1 day later than time but at the same time of day.
-
#sameTimeNextHour ⇒ Object
Return a new time that is 1 hour later than time.
-
#sameTimeNextMonth ⇒ Object
Return a new time that is 1 month later than time but at the same time of day.
-
#sameTimeNextQuarter ⇒ Object
Return a new time that is 1 quarter later than time but at the same time of day.
-
#sameTimeNextWeek ⇒ Object
Return a new time that is 1 week later than time but at the same time of day.
-
#sameTimeNextYear ⇒ Object
Return a new time that is 1 year later than time but at the same time of day.
-
#secondsOfDay(tz = nil) ⇒ Object
Returns the total number of seconds of the day.
- #strftime(format) ⇒ Object
- #to_a ⇒ Object
-
#to_i ⇒ Object
Return the seconds since Epoch.
-
#to_s(format = nil, tz = nil) ⇒ Object
This function is just a wrapper around Time.strftime().
-
#upto(endDate, step = 1) ⇒ Object
Iterator that executes the block until time has reached endDate increasing time by step on each iteration.
-
#utc ⇒ Object
Return the time object in UTC.
-
#wday ⇒ Object
Return the day of the week.
-
#weeksTo(date) ⇒ Object
Return the number of weeks between this time and date.
-
#year ⇒ Object
Return the year.
-
#yearsTo(date) ⇒ Object
Return the number of years between this time and date.
Constructor Details
#initialize(t = nil) ⇒ TjTime
call-seq:
TjTime() -> TjTime (now)
TjTime(tjtime) -> TjTime
TjTime(time, timezone) -> TjTime
TjTime(str) -> TjTime
TjTime(secs) -> TjTime
The constructor is overloaded and accepts 4 kinds of arguments. If t is a Time object it’s assumed to be in local time. If it’s a string, it is parsed as a date. Or else it is interpreted as seconds after Epoch.
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/taskjuggler/TjTime.rb', line 42 def initialize(t = nil) case t when nil @time = Time.now when Time @time = t when TjTime @time = t.time when String parse(t) when Array @time = Time.mktime(*t) else @time = Time.at(t) end end |
Instance Attribute Details
#time ⇒ Object (readonly)
Returns the value of attribute time.
24 25 26 |
# File 'lib/taskjuggler/TjTime.rb', line 24 def time @time end |
Class Method Details
.checkTimeZone(zone) ⇒ Object
Check if zone
is a valid time zone.
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/taskjuggler/TjTime.rb', line 60 def TjTime.checkTimeZone(zone) return true if zone == 'UTC' # Valid time zones must be of the form 'Region/City' return false unless zone.include?('/') # Save curent value of TZ tz = ENV['TZ'] ENV['TZ'] = zone newZone = Time.new.zone # If the time zone is valid, the OS can convert a zone like # 'America/Denver' into 'MST'. Unknown time zones are either not # converted or cause a fallback to UTC. # Since glibc 2.10 Time.new.zone only return the region for illegal # zones instead of the full zone string like it does on earlier # versions. region = zone[0..zone.index('/') - 1] res = (newZone != zone && newZone != region && newZone != 'UTC') # Restore TZ if it was set earlier. if tz ENV['TZ'] = tz else ENV.delete('TZ') end res end |
.setTimeZone(zone) ⇒ Object
Set a new active time zone. zone must be a valid String known to the underlying operating system.
89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/taskjuggler/TjTime.rb', line 89 def TjTime.setTimeZone(zone) unless zone && TjTime.checkTimeZone(zone) raise "Illegal time zone #{zone}" end oldTimeZone = @@tz @@tz = zone ENV['TZ'] = zone oldTimeZone end |
Instance Method Details
#%(val) ⇒ Object
Convert the time to seconds since Epoch and return the module of val.
140 141 142 |
# File 'lib/taskjuggler/TjTime.rb', line 140 def %(val) @time.to_i % val end |
#+(secs) ⇒ Object
Add secs number of seconds to the time.
125 126 127 |
# File 'lib/taskjuggler/TjTime.rb', line 125 def +(secs) TjTime.new(@time.to_i + secs) end |
#-(arg) ⇒ Object
Substract arg number of seconds or return the number of seconds between arg and this time.
131 132 133 134 135 136 137 |
# File 'lib/taskjuggler/TjTime.rb', line 131 def -(arg) if arg.is_a?(TjTime) @time - arg.time else TjTime.new(@time.to_i - arg) end end |
#<(t) ⇒ Object
Return true if time is smaller than t.
145 146 147 148 |
# File 'lib/taskjuggler/TjTime.rb', line 145 def <(t) return false unless t @time < t.time end |
#<=(t) ⇒ Object
Return true if time is smaller or equal than t.
151 152 153 154 |
# File 'lib/taskjuggler/TjTime.rb', line 151 def <=(t) return false unless t @time <= t.time end |
#<=>(t) ⇒ Object
Coparison operator for time with another time t.
175 176 177 178 |
# File 'lib/taskjuggler/TjTime.rb', line 175 def <=>(t) return -1 unless t @time <=> t.time end |
#==(t) ⇒ Object
Return true if time and t are identical.
169 170 171 172 |
# File 'lib/taskjuggler/TjTime.rb', line 169 def ==(t) return false unless t @time == t.time end |
#>(t) ⇒ Object
Return true if time is larger than t.
157 158 159 160 |
# File 'lib/taskjuggler/TjTime.rb', line 157 def >(t) return true unless t @time > t.time end |
#>=(t) ⇒ Object
Return true if time is larger or equal than t.
163 164 165 166 |
# File 'lib/taskjuggler/TjTime.rb', line 163 def >=(t) return true unless t @time >= t.time end |
#align(clock) ⇒ Object
Align the date to a time grid. The grid distance is determined by clock.
108 109 110 |
# File 'lib/taskjuggler/TjTime.rb', line 108 def align(clock) TjTime.new((localtime.to_i / clock) * clock) end |
#beginOfHour ⇒ Object
Normalize time to the beginning of the current hour.
191 192 193 194 195 |
# File 'lib/taskjuggler/TjTime.rb', line 191 def beginOfHour sec, min, hour, day, month, year = localtime.to_a sec = min = 0 TjTime.new([ year, month, day, hour, min, sec, 0 ]) end |
#beginOfMonth ⇒ Object
Normalize time to the beginning of the current month.
220 221 222 223 224 225 |
# File 'lib/taskjuggler/TjTime.rb', line 220 def beginOfMonth sec, min, hour, day, month, year = localtime.to_a sec = min = hour = 0 day = 1 TjTime.new([ year, month, day, hour, min, sec, 0 ]) end |
#beginOfQuarter ⇒ Object
Normalize time to the beginning of the current quarter.
228 229 230 231 232 233 234 |
# File 'lib/taskjuggler/TjTime.rb', line 228 def beginOfQuarter sec, min, hour, day, month, year = localtime.to_a sec = min = hour = 0 day = 1 month = ((month - 1) % 3 ) + 1 TjTime.new([ year, month, day, hour, min, sec, 0 ]) end |
#beginOfWeek(startMonday) ⇒ Object
Normalize time to the beginning of the current week. startMonday determines whether the week should start on Monday or Sunday.
206 207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/taskjuggler/TjTime.rb', line 206 def beginOfWeek(startMonday) t = localtime.to_a # Set time to noon, 12:00:00 t[0, 3] = [ 0, 0, 12 ] weekday = t[6] t.slice!(6, 4) t.reverse! # Substract the number of days determined by the weekday t[6] and set time # to midnight of that day. (TjTime.new(Time.local(*t)) - (weekday - (startMonday ? 1 : 0)) * 60 * 60 * 24).midnight end |
#beginOfYear ⇒ Object
Normalize time to the beginning of the current year.
237 238 239 240 241 242 |
# File 'lib/taskjuggler/TjTime.rb', line 237 def beginOfYear sec, min, hour, day, month, year = localtime.to_a sec = min = hour = 0 day = month = 1 TjTime.new([ year, month, day, hour, min, sec, 0 ]) end |
#day ⇒ Object
Return the day of the month (1..n).
404 405 406 |
# File 'lib/taskjuggler/TjTime.rb', line 404 def day localtime.day end |
#daysTo(date) ⇒ Object
Return the number of days between this time and date. The result is always rounded up.
336 337 338 |
# File 'lib/taskjuggler/TjTime.rb', line 336 def daysTo(date) countIntervals(date, :sameTimeNextDay) end |
#hour ⇒ Object
Return the hours of the day (0..23)
399 400 401 |
# File 'lib/taskjuggler/TjTime.rb', line 399 def hour localtime.hour end |
#hoursLater(hours) ⇒ Object
Return a new time that is hours later than time.
245 246 247 |
# File 'lib/taskjuggler/TjTime.rb', line 245 def hoursLater(hours) TjTime.new(@time + hours * 3600) end |
#hoursTo(date) ⇒ Object
Return the number of hours between this time and date. The result is always rounded up.
329 330 331 332 |
# File 'lib/taskjuggler/TjTime.rb', line 329 def hoursTo(date) t1, t2 = order(date) ((t2 - t1) / 3600).ceil end |
#midnight ⇒ Object
Normalize time to the beginning of the current day.
198 199 200 201 202 |
# File 'lib/taskjuggler/TjTime.rb', line 198 def midnight sec, min, hour, day, month, year = localtime.to_a sec = min = hour = 0 TjTime.new([ year, month, day, hour, min, sec, 0 ]) end |
#month ⇒ Object Also known as: mon
Return the month of the year (1..12)
409 410 411 |
# File 'lib/taskjuggler/TjTime.rb', line 409 def month localtime.month end |
#monthsTo(date) ⇒ Object
Return the number of months between this time and date. The result is always rounded up.
348 349 350 |
# File 'lib/taskjuggler/TjTime.rb', line 348 def monthsTo(date) countIntervals(date, :sameTimeNextMonth) end |
#nextDayOfWeek(dow) ⇒ Object
Return the start of the next dow day of week after date. dow must be 0 for Sundays, 1 for Mondays and 6 for Saturdays. If date is a Tuesday and dow is 5 (Friday) the date of next Friday 0:00 will be returned. If date is a Tuesday and dow is 2 (Tuesday) the date of the next Tuesday will be returned.
319 320 321 322 323 324 325 |
# File 'lib/taskjuggler/TjTime.rb', line 319 def nextDayOfWeek(dow) raise "Day of week must be 0 - 6." unless dow >= 0 && dow <= 6 d = midnight.sameTimeNextDay currentDoW = d.strftime('%w').to_i 1.upto((dow + 7 - currentDoW) % 7) { |i| d = d.sameTimeNextDay } d end |
#quartersTo(date) ⇒ Object
Return the number of quarters between this time and date. The result is always rounded up.
354 355 356 |
# File 'lib/taskjuggler/TjTime.rb', line 354 def quartersTo(date) countIntervals(date, :sameTimeNextQuarter) end |
#sameTimeNextDay ⇒ Object
Return a new time that is 1 day later than time but at the same time of day.
256 257 258 259 260 261 262 263 264 265 266 |
# File 'lib/taskjuggler/TjTime.rb', line 256 def sameTimeNextDay sec, min, hour, day, month, year = localtime.to_a if (day += 1) > lastDayOfMonth(month, year) day = 1 if (month += 1) > 12 month = 1 year += 1 end end TjTime.new([ year, month, day, hour, min, sec, 0 ]) end |
#sameTimeNextHour ⇒ Object
Return a new time that is 1 hour later than time.
250 251 252 |
# File 'lib/taskjuggler/TjTime.rb', line 250 def sameTimeNextHour hoursLater(1) end |
#sameTimeNextMonth ⇒ Object
Return a new time that is 1 month later than time but at the same time of day.
284 285 286 287 288 289 290 291 292 293 |
# File 'lib/taskjuggler/TjTime.rb', line 284 def sameTimeNextMonth sec, min, hour, day, month, year = localtime.to_a monMax = month == 2 && leapYear?(year) ? 29 : MON_MAX[month] if (month += 1) > 12 month = 1 year += 1 end day = monMax if day >= lastDayOfMonth(month, year) TjTime.new([ year, month, day, hour, min, sec, 0 ]) end |
#sameTimeNextQuarter ⇒ Object
Return a new time that is 1 quarter later than time but at the same time of day.
297 298 299 300 301 302 303 304 |
# File 'lib/taskjuggler/TjTime.rb', line 297 def sameTimeNextQuarter sec, min, hour, day, month, year = localtime.to_a if (month += 3) > 12 month -= 12 year += 1 end TjTime.new([ year, month, day, hour, min, sec, 0 ]) end |
#sameTimeNextWeek ⇒ Object
Return a new time that is 1 week later than time but at the same time of day.
270 271 272 273 274 275 276 277 278 279 280 |
# File 'lib/taskjuggler/TjTime.rb', line 270 def sameTimeNextWeek sec, min, hour, day, month, year = localtime.to_a if (day += 7) > lastDayOfMonth(month, year) day -= lastDayOfMonth(month, year) if (month += 1) > 12 month = 1 year += 1 end end TjTime.new([ year, month, day, hour, min, sec, 0 ]) end |
#sameTimeNextYear ⇒ Object
Return a new time that is 1 year later than time but at the same time of day.
308 309 310 311 312 |
# File 'lib/taskjuggler/TjTime.rb', line 308 def sameTimeNextYear sec, min, hour, day, month, year = localtime.to_a year += 1 TjTime.new([ year, month, day, hour, min, sec, 0]) end |
#secondsOfDay(tz = nil) ⇒ Object
Returns the total number of seconds of the day. The time is assumed to be in the time zone specified by tz.
119 120 121 122 |
# File 'lib/taskjuggler/TjTime.rb', line 119 def secondsOfDay(tz = nil) lt = localtime (lt.to_i + lt.gmt_offset) % (60 * 60 * 24) end |
#strftime(format) ⇒ Object
389 390 391 |
# File 'lib/taskjuggler/TjTime.rb', line 389 def strftime(format) localtime.strftime(format) end |
#to_a ⇒ Object
385 386 387 |
# File 'lib/taskjuggler/TjTime.rb', line 385 def to_a localtime.to_a end |
#to_i ⇒ Object
Return the seconds since Epoch.
381 382 383 |
# File 'lib/taskjuggler/TjTime.rb', line 381 def to_i localtime.to_i end |
#to_s(format = nil, tz = nil) ⇒ Object
This function is just a wrapper around Time.strftime(). In case @time is nil, it returns ‘unkown’.
366 367 368 369 370 371 372 373 374 375 376 377 378 |
# File 'lib/taskjuggler/TjTime.rb', line 366 def to_s(format = nil, tz = nil) return 'unknown' if @time.nil? t = tz == 'UTC' ? gmtime : localtime if format.nil? fmt = '%Y-%m-%d-%H:%M' + (@time.sec == 0 ? '' : ':%S') + '-%z' else # Handle TJ specific extensions to the strftime format. fmt = format.sub(/%Q/, "#{((t.mon - 1) / 3) + 1}") end # Always report values in local timezone t.strftime(fmt) end |
#upto(endDate, step = 1) ⇒ Object
Iterator that executes the block until time has reached endDate increasing time by step on each iteration.
182 183 184 185 186 187 188 |
# File 'lib/taskjuggler/TjTime.rb', line 182 def upto(endDate, step = 1) t = @time while t < endDate.time yield(TjTime.new(t)) t += step end end |
#utc ⇒ Object
Return the time object in UTC.
113 114 115 |
# File 'lib/taskjuggler/TjTime.rb', line 113 def utc TjTime.new(@time.dup.gmtime) end |
#wday ⇒ Object
Return the day of the week. 0 for Sunday, 1 for Monday and so on.
394 395 396 |
# File 'lib/taskjuggler/TjTime.rb', line 394 def wday localtime.wday end |
#weeksTo(date) ⇒ Object
Return the number of weeks between this time and date. The result is always rounded up.
342 343 344 |
# File 'lib/taskjuggler/TjTime.rb', line 342 def weeksTo(date) countIntervals(date, :sameTimeNextWeek) end |
#year ⇒ Object
Return the year.
416 417 418 |
# File 'lib/taskjuggler/TjTime.rb', line 416 def year localtime.year end |
#yearsTo(date) ⇒ Object
Return the number of years between this time and date. The result is always rounded up.
360 361 362 |
# File 'lib/taskjuggler/TjTime.rb', line 360 def yearsTo(date) countIntervals(date, :sameTimeNextYear) end |