The TjTime class extends the original Ruby class Time with lots of TaskJuggler specific additional functionality. This is mostly for handling time zones.
The number of days per month. Leap years are taken care of separately.
Check if zone
is a valid time zone.
# File lib/taskjuggler/TjTime.rb, line 62 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 40 def initialize(t = nil) @timeZone = @@tz case t when nil @time = Time.now when Time @time = t @timeZone = nil when TjTime @time = t.time @timeZone = nil 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 91 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 105 def TjTime.timeZone @@tz end
Convert the time to seconds since Epoch and return the module of val.
# File lib/taskjuggler/TjTime.rb, line 142 def %(val) @time.to_i % val end
Add secs number of seconds to the time.
# File lib/taskjuggler/TjTime.rb, line 127 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 133 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 147 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 153 def <=(t) return false unless t @time <= t.time end
Coparison operator for time with another time t.
# File lib/taskjuggler/TjTime.rb, line 177 def <=>(t) return -1 unless t @time <=> t.time end
Return true if time and t are identical.
# File lib/taskjuggler/TjTime.rb, line 171 def ==(t) return false unless t @time == t.time end
Return true if time is larger than t.
# File lib/taskjuggler/TjTime.rb, line 159 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 165 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 110 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 193 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 222 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 230 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 208 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 239 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 338 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 247 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 331 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 200 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 350 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 321 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 356 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 258 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 252 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 286 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 299 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 272 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 310 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 121 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 368 def to_s(format = nil) return 'unknown' if @time.nil? 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(%r%Q/, "#{((localtime.mon - 1) / 3) + 1}") end # Always report values in local timezone localtime.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 184 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 115 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 344 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 362 def yearsTo(date) countIntervals(date, :sameTimeNextYear) end