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.
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/taskjuggler/TjTime.rb', line 43 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.
25 26 27 |
# File 'lib/taskjuggler/TjTime.rb', line 25 def time @time end |
Class Method Details
.checkTimeZone(zone) ⇒ Object
Check if zone
is a valid time zone.
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 86 |
# File 'lib/taskjuggler/TjTime.rb', line 61 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.
90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/taskjuggler/TjTime.rb', line 90 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.
141 142 143 |
# File 'lib/taskjuggler/TjTime.rb', line 141 def %(val) @time.to_i % val end |
#+(secs) ⇒ Object
Add secs number of seconds to the time.
126 127 128 |
# File 'lib/taskjuggler/TjTime.rb', line 126 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.
132 133 134 135 136 137 138 |
# File 'lib/taskjuggler/TjTime.rb', line 132 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.
146 147 148 149 |
# File 'lib/taskjuggler/TjTime.rb', line 146 def <(t) return false unless t @time < t.time end |
#<=(t) ⇒ Object
Return true if time is smaller or equal than t.
152 153 154 155 |
# File 'lib/taskjuggler/TjTime.rb', line 152 def <=(t) return false unless t @time <= t.time end |
#<=>(t) ⇒ Object
Coparison operator for time with another time t.
176 177 178 179 |
# File 'lib/taskjuggler/TjTime.rb', line 176 def <=>(t) return -1 unless t @time <=> t.time end |
#==(t) ⇒ Object
Return true if time and t are identical.
170 171 172 173 |
# File 'lib/taskjuggler/TjTime.rb', line 170 def ==(t) return false unless t @time == t.time end |
#>(t) ⇒ Object
Return true if time is larger than t.
158 159 160 161 |
# File 'lib/taskjuggler/TjTime.rb', line 158 def >(t) return true unless t @time > t.time end |
#>=(t) ⇒ Object
Return true if time is larger or equal than t.
164 165 166 167 |
# File 'lib/taskjuggler/TjTime.rb', line 164 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.
109 110 111 |
# File 'lib/taskjuggler/TjTime.rb', line 109 def align(clock) TjTime.new((localtime.to_i / clock) * clock) end |
#beginOfHour ⇒ Object
Normalize time to the beginning of the current hour.
192 193 194 195 196 |
# File 'lib/taskjuggler/TjTime.rb', line 192 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.
221 222 223 224 225 226 |
# File 'lib/taskjuggler/TjTime.rb', line 221 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.
229 230 231 232 233 234 235 |
# File 'lib/taskjuggler/TjTime.rb', line 229 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.
207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/taskjuggler/TjTime.rb', line 207 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.
238 239 240 241 242 243 |
# File 'lib/taskjuggler/TjTime.rb', line 238 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).
405 406 407 |
# File 'lib/taskjuggler/TjTime.rb', line 405 def day localtime.day end |
#daysTo(date) ⇒ Object
Return the number of days between this time and date. The result is always rounded up.
337 338 339 |
# File 'lib/taskjuggler/TjTime.rb', line 337 def daysTo(date) countIntervals(date, :sameTimeNextDay) end |
#hour ⇒ Object
Return the hours of the day (0..23)
400 401 402 |
# File 'lib/taskjuggler/TjTime.rb', line 400 def hour localtime.hour end |
#hoursLater(hours) ⇒ Object
Return a new time that is hours later than time.
246 247 248 |
# File 'lib/taskjuggler/TjTime.rb', line 246 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.
330 331 332 333 |
# File 'lib/taskjuggler/TjTime.rb', line 330 def hoursTo(date) t1, t2 = order(date) ((t2 - t1) / 3600).ceil end |
#midnight ⇒ Object
Normalize time to the beginning of the current day.
199 200 201 202 203 |
# File 'lib/taskjuggler/TjTime.rb', line 199 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)
410 411 412 |
# File 'lib/taskjuggler/TjTime.rb', line 410 def month localtime.month end |
#monthsTo(date) ⇒ Object
Return the number of months between this time and date. The result is always rounded up.
349 350 351 |
# File 'lib/taskjuggler/TjTime.rb', line 349 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.
320 321 322 323 324 325 326 |
# File 'lib/taskjuggler/TjTime.rb', line 320 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.
355 356 357 |
# File 'lib/taskjuggler/TjTime.rb', line 355 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.
257 258 259 260 261 262 263 264 265 266 267 |
# File 'lib/taskjuggler/TjTime.rb', line 257 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.
251 252 253 |
# File 'lib/taskjuggler/TjTime.rb', line 251 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.
285 286 287 288 289 290 291 292 293 294 |
# File 'lib/taskjuggler/TjTime.rb', line 285 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.
298 299 300 301 302 303 304 305 |
# File 'lib/taskjuggler/TjTime.rb', line 298 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.
271 272 273 274 275 276 277 278 279 280 281 |
# File 'lib/taskjuggler/TjTime.rb', line 271 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.
309 310 311 312 313 |
# File 'lib/taskjuggler/TjTime.rb', line 309 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.
120 121 122 123 |
# File 'lib/taskjuggler/TjTime.rb', line 120 def secondsOfDay(tz = nil) lt = localtime (lt.to_i + lt.gmt_offset) % (60 * 60 * 24) end |
#strftime(format) ⇒ Object
390 391 392 |
# File 'lib/taskjuggler/TjTime.rb', line 390 def strftime(format) localtime.strftime(format) end |
#to_a ⇒ Object
386 387 388 |
# File 'lib/taskjuggler/TjTime.rb', line 386 def to_a localtime.to_a end |
#to_i ⇒ Object
Return the seconds since Epoch.
382 383 384 |
# File 'lib/taskjuggler/TjTime.rb', line 382 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’.
367 368 369 370 371 372 373 374 375 376 377 378 379 |
# File 'lib/taskjuggler/TjTime.rb', line 367 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.
183 184 185 186 187 188 189 |
# File 'lib/taskjuggler/TjTime.rb', line 183 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.
114 115 116 |
# File 'lib/taskjuggler/TjTime.rb', line 114 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.
395 396 397 |
# File 'lib/taskjuggler/TjTime.rb', line 395 def wday localtime.wday end |
#weeksTo(date) ⇒ Object
Return the number of weeks between this time and date. The result is always rounded up.
343 344 345 |
# File 'lib/taskjuggler/TjTime.rb', line 343 def weeksTo(date) countIntervals(date, :sameTimeNextWeek) end |
#year ⇒ Object
Return the year.
417 418 419 |
# File 'lib/taskjuggler/TjTime.rb', line 417 def year localtime.year end |
#yearsTo(date) ⇒ Object
Return the number of years between this time and date. The result is always rounded up.
361 362 363 |
# File 'lib/taskjuggler/TjTime.rb', line 361 def yearsTo(date) countIntervals(date, :sameTimeNextYear) end |