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

time[R]

Public Class Methods

checkTimeZone(zone) click to toggle source

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
TjTime() → TjTime (now) click to toggle source
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.

# 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
setTimeZone(zone) click to toggle source

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
timeZone() click to toggle source

Return the name of the currently active time zone.

# File lib/taskjuggler/TjTime.rb, line 103
def TjTime.timeZone
  @@tz
end

Public Instance Methods

%(val) click to toggle source

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
+(secs) click to toggle source

Add secs number of seconds to the time.

# File lib/taskjuggler/TjTime.rb, line 125
def +(secs)
  TjTime.new(@time.to_i + secs)
end
-(arg) click to toggle source

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
<(t) click to toggle source

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
<=(t) click to toggle source

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
<=>(t) click to toggle source

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
==(t) click to toggle source

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
>(t) click to toggle source

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
>=(t) click to toggle source

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(clock) click to toggle source

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
beginOfHour() click to toggle source

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
beginOfMonth() click to toggle source

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
beginOfQuarter() click to toggle source

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
beginOfWeek(startMonday) click to toggle source

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
beginOfYear() click to toggle source

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
day() click to toggle source

Return the day of the month (1..n).

# File lib/taskjuggler/TjTime.rb, line 404
def day
  localtime.day
end
daysTo(date) click to toggle source

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
hour() click to toggle source

Return the hours of the day (0..23)

# File lib/taskjuggler/TjTime.rb, line 399
def hour
  localtime.hour
end
hoursLater(hours) click to toggle source

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
hoursTo(date) click to toggle source

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
midnight() click to toggle source

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
mon()
Alias for: month
month() click to toggle source

Return the month of the year (1..12)

# File lib/taskjuggler/TjTime.rb, line 409
def month
  localtime.month
end
Also aliased as: mon
monthsTo(date) click to toggle source

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
nextDayOfWeek(dow) click to toggle source

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
quartersTo(date) click to toggle source

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
sameTimeNextDay() click to toggle source

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
sameTimeNextHour() click to toggle source

Return a new time that is 1 hour later than time.

# File lib/taskjuggler/TjTime.rb, line 250
def sameTimeNextHour
  hoursLater(1)
end
sameTimeNextMonth() click to toggle source

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
sameTimeNextQuarter() click to toggle source

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
sameTimeNextWeek() click to toggle source

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
sameTimeNextYear() click to toggle source

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
secondsOfDay(tz = nil) click to toggle source

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
strftime(format) click to toggle source
# File lib/taskjuggler/TjTime.rb, line 389
def strftime(format)
  localtime.strftime(format)
end
to_a() click to toggle source
# File lib/taskjuggler/TjTime.rb, line 385
def to_a
  localtime.to_a
end
to_i() click to toggle source

Return the seconds since Epoch.

# File lib/taskjuggler/TjTime.rb, line 381
def to_i
  localtime.to_i
end
to_s(format = nil, tz = nil) click to toggle source

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
upto(endDate, step = 1) { |tj_time| ... } click to toggle source

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
utc() click to toggle source

Return the time object in UTC.

# File lib/taskjuggler/TjTime.rb, line 113
def utc
  TjTime.new(@time.dup.gmtime)
end
wday() click to toggle source

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
weeksTo(date) click to toggle source

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
year() click to toggle source

Return the year.

# File lib/taskjuggler/TjTime.rb, line 416
def year
  localtime.year
end
yearsTo(date) click to toggle source

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