Class TaskJuggler::TjTime
In: lib/taskjuggler/TjTime.rb
Parent: Object

The TjTime class extends the original Ruby class Time with lots of TaskJuggler specific additional functionality. This is mostly for handling time zones.

Methods

Constants

MON_MAX = [ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]   The number of days per month. Leap years are taken care of separately.

Attributes

time  [R] 
timeZone  [R] 

Public Class methods

Check if zone is a valid time zone.

[Source]

# File lib/taskjuggler/TjTime.rb, line 64
    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.

[Source]

# File lib/taskjuggler/TjTime.rb, line 42
    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.

[Source]

# File lib/taskjuggler/TjTime.rb, line 93
    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.

[Source]

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

Public Instance methods

Convert the time to seconds since Epoch and return the module of val.

[Source]

# File lib/taskjuggler/TjTime.rb, line 144
    def %(val)
      @time.to_i % val
    end

Add secs number of seconds to the time.

[Source]

# File lib/taskjuggler/TjTime.rb, line 129
    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.

[Source]

# File lib/taskjuggler/TjTime.rb, line 135
    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.

[Source]

# File lib/taskjuggler/TjTime.rb, line 149
    def <(t)
      return false unless t
      @time < t.time
    end

Return true if time is smaller or equal than t.

[Source]

# File lib/taskjuggler/TjTime.rb, line 155
    def <=(t)
      return false unless t
      @time <= t.time
    end

Coparison operator for time with another time t.

[Source]

# File lib/taskjuggler/TjTime.rb, line 179
    def <=>(t)
      return -1 unless t
      @time <=> t.time
    end

Return true if time and t are identical.

[Source]

# File lib/taskjuggler/TjTime.rb, line 173
    def ==(t)
      return false unless t
      @time == t.time
    end

Return true if time is larger than t.

[Source]

# File lib/taskjuggler/TjTime.rb, line 161
    def >(t)
      return true unless t
      @time > t.time
    end

Return true if time is larger or equal than t.

[Source]

# File lib/taskjuggler/TjTime.rb, line 167
    def >=(t)
      return true unless t
      @time >= t.time
    end

Align the date to a time grid. The grid distance is determined by clock.

[Source]

# File lib/taskjuggler/TjTime.rb, line 112
    def align(clock)
      TjTime.new((localtime.to_i / clock) * clock)
    end

Normalize time to the beginning of the current hour.

[Source]

# File lib/taskjuggler/TjTime.rb, line 195
    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.

[Source]

# File lib/taskjuggler/TjTime.rb, line 224
    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.

[Source]

# File lib/taskjuggler/TjTime.rb, line 232
    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.

[Source]

# File lib/taskjuggler/TjTime.rb, line 210
    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.

[Source]

# File lib/taskjuggler/TjTime.rb, line 241
    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).

[Source]

# File lib/taskjuggler/TjTime.rb, line 403
    def day
      localtime.day
    end

Return the number of days between this time and date. The result is always rounded up.

[Source]

# File lib/taskjuggler/TjTime.rb, line 340
    def daysTo(date)
      countIntervals(date, :sameTimeNextDay)
    end

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

[Source]

# File lib/taskjuggler/TjTime.rb, line 398
    def hour
      localtime.hour
    end

Return a new time that is hours later than time.

[Source]

# File lib/taskjuggler/TjTime.rb, line 249
    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.

[Source]

# File lib/taskjuggler/TjTime.rb, line 333
    def hoursTo(date)
      t1, t2 = order(date)
      ((t2 - t1) / 3600).ceil
    end

Normalize time to the beginning of the current day.

[Source]

# File lib/taskjuggler/TjTime.rb, line 202
    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

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

[Source]

# File lib/taskjuggler/TjTime.rb, line 408
    def month
      localtime.month
    end

Return the abbreviated month name and the full year. E. g. ‘Feb 1972’.

[Source]

# File lib/taskjuggler/TjTime.rb, line 436
    def monthAndYear
      localtime.strftime('%b %Y')
    end

Return the number of months between this time and date. The result is always rounded up.

[Source]

# File lib/taskjuggler/TjTime.rb, line 352
    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.

[Source]

# File lib/taskjuggler/TjTime.rb, line 323
    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 the quarter prefixed by a ‘Q’.

[Source]

# File lib/taskjuggler/TjTime.rb, line 425
    def quarterName
      "Q#{(localtime.mon / 3) + 1}"
    end

Return the number of quarters between this time and date. The result is always rounded up.

[Source]

# File lib/taskjuggler/TjTime.rb, line 358
    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.

[Source]

# File lib/taskjuggler/TjTime.rb, line 260
    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.

[Source]

# File lib/taskjuggler/TjTime.rb, line 254
    def sameTimeNextHour
      hoursLater(1)
    end

Return a new time that is 1 month later than time but at the same time of day.

[Source]

# File lib/taskjuggler/TjTime.rb, line 288
    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.

[Source]

# File lib/taskjuggler/TjTime.rb, line 301
    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.

[Source]

# File lib/taskjuggler/TjTime.rb, line 274
    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.

[Source]

# File lib/taskjuggler/TjTime.rb, line 312
    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.

[Source]

# File lib/taskjuggler/TjTime.rb, line 123
    def secondsOfDay(tz = nil)
      lt = localtime
      (lt.to_i + lt.gmt_offset) % (60 * 60 * 24)
    end

Return the abbreviated month name.

[Source]

# File lib/taskjuggler/TjTime.rb, line 420
    def shortMonthName
      localtime.strftime('%b')
    end

[Source]

# File lib/taskjuggler/TjTime.rb, line 388
    def strftime(format)
      localtime.strftime(format)
    end

[Source]

# File lib/taskjuggler/TjTime.rb, line 384
    def to_a
      localtime.to_a
    end

Return the seconds since Epoch.

[Source]

# File lib/taskjuggler/TjTime.rb, line 380
    def to_i
      localtime.to_i
    end

This function is just a wrapper around Time.strftime(). In case @time is nil, it returns ‘unkown’.

[Source]

# File lib/taskjuggler/TjTime.rb, line 370
    def to_s(format = nil)
      return 'unknown' if @time.nil?
      if format.nil?
        format = '%Y-%m-%d-%H:%M' + (@time.sec == 0 ? '' : ':%S') + '-%z'
      end
      # Always report values in local timezone
      localtime.strftime(format)
    end

Iterator that executes the block until time has reached endDate increasing time by step on each iteration.

[Source]

# File lib/taskjuggler/TjTime.rb, line 186
    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.

[Source]

# File lib/taskjuggler/TjTime.rb, line 117
    def utc
      TjTime.new(@time.dup.gmtime)
    end

Return the day of the week. 0 for Sunday, 1 for Monday and so on.

[Source]

# File lib/taskjuggler/TjTime.rb, line 393
    def wday
      localtime.wday
    end

Return the week number. weekStartsMonday specifies wheter the counting should be for weeks starting Mondays or Sundays.

[Source]

# File lib/taskjuggler/TjTime.rb, line 431
    def week(weekStartsMonday)
      localtime.strftime(weekStartsMonday ? '%W' : '%U')
    end

Return the abbreviated weekday and the full date. E. g. ‘Sat 2007-11-03’.

[Source]

# File lib/taskjuggler/TjTime.rb, line 441
    def weekdayAndDate
      localtime.strftime('%A %Y-%m-%d')
    end

Return the number of weeks between this time and date. The result is always rounded up.

[Source]

# File lib/taskjuggler/TjTime.rb, line 346
    def weeksTo(date)
      countIntervals(date, :sameTimeNextWeek)
    end

Return the year.

[Source]

# File lib/taskjuggler/TjTime.rb, line 415
    def year
      localtime.year
    end

Return the number of years between this time and date. The result is always rounded up.

[Source]

# File lib/taskjuggler/TjTime.rb, line 364
    def yearsTo(date)
      countIntervals(date, :sameTimeNextYear)
    end

[Validate]