class TZInfo::TimeOrDateTime

:nodoc:
@private
timestamp (seconds since 1970-01-01 00:00:00).
Used by TZInfo internally to represent either a Time, DateTime or integer

def self.wrap(timeOrDateTime)

the passed in value will be used.
If a TimeOrDateTime is passed in, no new TimeOrDateTime will be constructed,
timeOrDateTime can be a Time, DateTime, integer timestamp or TimeOrDateTime.

returned.
to_orig will be called on the result and the result of to_orig will be
and passed to the block. The result of the block must be a TimeOrDateTime.
timeOrDateTime. If a block is specified, a TimeOrDateTime is constructed
If no block is given, returns a TimeOrDateTime wrapping the given
def self.wrap(timeOrDateTime)      
  t = timeOrDateTime.is_a?(TimeOrDateTime) ? timeOrDateTime : TimeOrDateTime.new(timeOrDateTime)        
  
  if block_given?
    t = yield t
    
    if timeOrDateTime.is_a?(TimeOrDateTime)
      t          
    elsif timeOrDateTime.is_a?(Time)
      t.to_time
    elsif timeOrDateTime.is_a?(DateTime)
      t.to_datetime
    else
      t.to_i
    end        
  else
    t
  end
end

def +(seconds)

range for Times, then an exception will be raised by the Time class.
If the original type is a Time and the resulting calculation goes out of
TimeOrDateTime, preserving what the original constructed type was.
Adds a number of seconds to the TimeOrDateTime. Returns a new
def +(seconds)
  if seconds == 0
    self
  else
    if @orig.is_a?(DateTime)
      TimeOrDateTime.new(@orig + OffsetRationals.rational_for_offset(seconds))
    else
      # + defined for Time and integer timestamps
      TimeOrDateTime.new(@orig + seconds)
    end
  end
end

def -(seconds)

range for Times, then an exception will be raised by the Time class.
If the original type is a Time and the resulting calculation goes out of
TimeOrDateTime, preserving what the original constructed type was.
Subtracts a number of seconds from the TimeOrDateTime. Returns a new
def -(seconds)
  self + (-seconds)
end

def <=>(timeOrDateTime)

Milliseconds and smaller units are ignored in the comparison.

receiver is less than, equal to, or greater than timeOrDateTime.
timestamp or TimeOrDateTime. Returns -1, 0 or +1 depending whether the
Compares this TimeOrDateTime with another Time, DateTime, integer
def <=>(timeOrDateTime)
  if timeOrDateTime.is_a?(TimeOrDateTime)            
    orig = timeOrDateTime.to_orig
    
    if @orig.is_a?(DateTime) || orig.is_a?(DateTime)
      # If either is a DateTime, assume it is there for a reason 
      # (i.e. for range).
      to_datetime <=> timeOrDateTime.to_datetime
    elsif orig.is_a?(Time)
      to_time <=> timeOrDateTime.to_time
    else
      to_i <=> timeOrDateTime.to_i
    end        
  elsif @orig.is_a?(DateTime) || timeOrDateTime.is_a?(DateTime)
    # If either is a DateTime, assume it is there for a reason 
    # (i.e. for range).        
    to_datetime <=> TimeOrDateTime.wrap(timeOrDateTime).to_datetime
  elsif timeOrDateTime.is_a?(Time)
    to_time <=> timeOrDateTime
  else
    to_i <=> timeOrDateTime.to_i
  end
end

def add_with_convert(seconds)

based TimeOrDateTime.
timestamp or time to go out of the allowed range, converts to a DateTime
Similar to the + operator, but for cases where adding would cause a
def add_with_convert(seconds)
  if seconds == 0
    self
  else
    if @orig.is_a?(DateTime)
      TimeOrDateTime.new(@orig + OffsetRationals.rational_for_offset(seconds))
    else
      # A Time or timestamp.
      result = to_i + seconds
      
      if result < 0 || result > 2147483647
        result = TimeOrDateTime.new(to_datetime + OffsetRationals.rational_for_offset(seconds))
      else
        result = TimeOrDateTime.new(@orig + seconds)
      end
    end
  end
end

def eql?(todt)

TimeOrDateTime.
constructed with the same type (DateTime, Time or timestamp) as this
Returns true if todt represents the same time and was originally
def eql?(todt)
  todt.kind_of?(TimeOrDateTime) && to_orig.eql?(todt.to_orig)      
end

def hash

Returns a hash of this TimeOrDateTime.
def hash
  @orig.hash
end

def hour

Returns the hour of the day (0..23).
def hour
  if @time
    @time.hour
  elsif @datetime
    @datetime.hour
  else
    to_time.hour
  end
end

def initialize(timeOrDateTime)

ignored.
or an integer. If using a Time or DateTime, any time zone information is
Constructs a new TimeOrDateTime. timeOrDateTime can be a Time, DateTime
def initialize(timeOrDateTime)
  @time = nil
  @datetime = nil
  @timestamp = nil
  
  if timeOrDateTime.is_a?(Time)
    @time = timeOrDateTime        
    @time = Time.utc(@time.year, @time.mon, @time.mday, @time.hour, @time.min, @time.sec) unless @time.zone == 'UTC'        
    @orig = @time
  elsif timeOrDateTime.is_a?(DateTime)
    @datetime = timeOrDateTime
    @datetime = @datetime.new_offset(0) unless @datetime.offset == 0
    @orig = @datetime
  else
    @timestamp = timeOrDateTime.to_i
    @orig = @timestamp
  end
end

def inspect

Returns internal object state as a programmer-readable string.
def inspect
  "#<#{self.class}: #{@orig.inspect}>"
end

def mday

Returns the day of the month (1..n).
def mday
  if @time
    @time.mday
  elsif @datetime
    @datetime.mday
  else
    to_time.mday
  end
end

def min

Returns the minute of the hour (0..59).
def min
  if @time
    @time.min
  elsif @datetime
    @datetime.min
  else
    to_time.min
  end
end

def mon

Returns the month of the year (1..12).
def mon
  if @time
    @time.mon
  elsif @datetime
    @datetime.mon
  else
    to_time.mon
  end
end

def sec

Returns the second of the minute (0..60). (60 for a leap second).
def sec
  if @time
    @time.sec
  elsif @datetime
    @datetime.sec
  else
    to_time.sec
  end
end

def to_datetime

Returns the time as a DateTime.
def to_datetime
  unless @datetime
    @datetime = DateTime.new(year, mon, mday, hour, min, sec)
  end
  
  @datetime
end

def to_i

Returns the time as an integer timestamp.
def to_i
  unless @timestamp
    @timestamp = to_time.to_i
  end
  
  @timestamp
end

def to_orig

Returns the time as the original time passed to new.
def to_orig
  @orig
end

def to_s

Returns a string representation of the TimeOrDateTime.
def to_s
  if @orig.is_a?(Time)
    "Time: #{@orig.to_s}"
  elsif @orig.is_a?(DateTime)
    "DateTime: #{@orig.to_s}"
  else
    "Timestamp: #{@orig.to_s}"
  end
end

def to_time

Returns the time as a Time.
def to_time
  unless @time        
    if @timestamp 
      @time = Time.at(@timestamp).utc
    else
      @time = Time.utc(year, mon, mday, hour, min, sec)
    end
  end
  
  @time      
end

def year

Returns the year.
def year
  if @time
    @time.year
  elsif @datetime
    @datetime.year
  else
    to_time.year
  end
end