class TaskJuggler::TjTime
The TjTime
class extends the original Ruby class Time with lots of TaskJuggler
specific additional functionality. This is mostly for handling time zones.
Constants
- MON_MAX
The number of days per month. Leap years are taken care of separately.
Attributes
Public Class Methods
Check if zone
is a valid time zone.
# 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
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.
# 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
Set a new active time zone. zone must be a valid String
known to the underlying operating system.
# 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
Return the name of the currently active time zone.
# File lib/taskjuggler/TjTime.rb, line 103 def TjTime.timeZone @@tz end
Public Instance Methods
Convert the time to seconds since Epoch and return the module of val.
# File lib/taskjuggler/TjTime.rb, line 140 def %(val) @time.to_i % val end
Add secs number of seconds to the time.
# File lib/taskjuggler/TjTime.rb, line 125 def +(secs) TjTime.new(@time.to_i + secs) end
Substract arg number of seconds or return the number of seconds between arg and this time.
# 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
Return true if time is smaller than t.
# File lib/taskjuggler/TjTime.rb, line 145 def <(t) return false unless t @time < t.time end
Return true if time is smaller or equal than t.
# File lib/taskjuggler/TjTime.rb, line 151 def <=(t) return false unless t @time <= t.time end
Coparison operator for time with another time t.
# File lib/taskjuggler/TjTime.rb, line 175 def <=>(t) return -1 unless t @time <=> t.time end
Return true if time and t are identical.
# File lib/taskjuggler/TjTime.rb, line 169 def ==(t) return false unless t @time == t.time end
Return true if time is larger than t.
# File lib/taskjuggler/TjTime.rb, line 157 def >(t) return true unless t @time > t.time end
Return true if time is larger or equal than t.
# File lib/taskjuggler/TjTime.rb, line 163 def >=(t) return true unless t @time >= t.time end
Align the date to a time grid. The grid distance is determined by clock.
# File lib/taskjuggler/TjTime.rb, line 108 def align(clock) TjTime.new((localtime.to_i / clock) * clock) end
Normalize time to the beginning of the current hour.
# 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
Normalize time to the beginning of the current month.
# 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
Normalize time to the beginning of the current quarter.
# 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
Normalize time to the beginning of the current week. startMonday determines whether the week should start on Monday or Sunday.
# 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
Normalize time to the beginning of the current year.
# 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
Return the day of the month (1..n).
# File lib/taskjuggler/TjTime.rb, line 404 def day localtime.day end
Return the number of days between this time and date. The result is always rounded up.
# File lib/taskjuggler/TjTime.rb, line 336 def daysTo(date) countIntervals(date, :sameTimeNextDay) end
Return the hours of the day (0..23)
# File lib/taskjuggler/TjTime.rb, line 399 def hour localtime.hour end
Return a new time that is hours later than time.
# File lib/taskjuggler/TjTime.rb, line 245 def hoursLater(hours) TjTime.new(@time + hours * 3600) end
Return the number of hours between this time and date. The result is always rounded up.
# File lib/taskjuggler/TjTime.rb, line 329 def hoursTo(date) t1, t2 = order(date) ((t2 - t1) / 3600).ceil end
Normalize time to the beginning of the current day.
# 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
Return the month of the year (1..12)
# File lib/taskjuggler/TjTime.rb, line 409 def month localtime.month end
Return the number of months between this time and date. The result is always rounded up.
# File lib/taskjuggler/TjTime.rb, line 348 def monthsTo(date) countIntervals(date, :sameTimeNextMonth) end
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.
# 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
Return the number of quarters between this time and date. The result is always rounded up.
# File lib/taskjuggler/TjTime.rb, line 354 def quartersTo(date) countIntervals(date, :sameTimeNextQuarter) end
Return a new time that is 1 day later than time but at the same time of day.
# 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
Return a new time that is 1 hour later than time.
# File lib/taskjuggler/TjTime.rb, line 250 def sameTimeNextHour hoursLater(1) end
Return a new time that is 1 month later than time but at the same time of day.
# 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
Return a new time that is 1 quarter later than time but at the same time of day.
# 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
Return a new time that is 1 week later than time but at the same time of day.
# 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
Return a new time that is 1 year later than time but at the same time of day.
# 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
Returns the total number of seconds of the day. The time is assumed to be in the time zone specified by tz.
# File lib/taskjuggler/TjTime.rb, line 119 def secondsOfDay(tz = nil) lt = localtime (lt.to_i + lt.gmt_offset) % (60 * 60 * 24) end
# File lib/taskjuggler/TjTime.rb, line 389 def strftime(format) localtime.strftime(format) end
# File lib/taskjuggler/TjTime.rb, line 385 def to_a localtime.to_a end
Return the seconds since Epoch.
# File lib/taskjuggler/TjTime.rb, line 381 def to_i localtime.to_i end
This function is just a wrapper around Time.strftime(). In case @time is nil, it returns ‘unkown’.
# 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
Iterator that executes the block until time has reached endDate increasing time by step on each iteration.
# 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
Return the time object in UTC.
# File lib/taskjuggler/TjTime.rb, line 113 def utc TjTime.new(@time.dup.gmtime) end
Return the day of the week. 0 for Sunday, 1 for Monday and so on.
# File lib/taskjuggler/TjTime.rb, line 394 def wday localtime.wday end
Return the number of weeks between this time and date. The result is always rounded up.
# File lib/taskjuggler/TjTime.rb, line 342 def weeksTo(date) countIntervals(date, :sameTimeNextWeek) end
Return the year.
# File lib/taskjuggler/TjTime.rb, line 416 def year localtime.year end
Return the number of years between this time and date. The result is always rounded up.
# File lib/taskjuggler/TjTime.rb, line 360 def yearsTo(date) countIntervals(date, :sameTimeNextYear) end