class Timecop::TimeStackItem

:nodoc:
movements on a simple stack.
A data class for carrying around “time movement” objects. Makes it easy to keep track of the time

def compute_dst_adjustment(time)

def compute_dst_adjustment(time)
  return 0 if !(time.dst? ^ Time.now.dst?)
  return -1 * 60 * 60 if time.dst?
  return 60 * 60
end

def compute_travel_offset

def compute_travel_offset
  return nil if mock_type == :freeze
  time - Time.now_without_mock_time
end

def date

def date
  time.send(:to_date)
end

def datetime

def datetime
  # DateTime doesn't know about DST, so let's remove its presence
  our_offset = utc_offset + dst_adjustment
  fractions_of_a_second = time.to_f % 1
  DateTime.new(year, month, day, hour, min, sec + fractions_of_a_second,
               utc_offset_to_rational(our_offset))
end

def day

def day
  time.day
end

def dst_adjustment

def dst_adjustment
  @dst_adjustment
end

def hour

def hour
  time.hour
end

def initialize(mock_type, *args)

def initialize(mock_type, *args)
  raise "Unknown mock_type #{mock_type}" unless [:freeze, :travel].include?(mock_type)
  @mock_type      = mock_type
  @time           = parse_time(*args)
  @travel_offset  = compute_travel_offset
  @dst_adjustment = compute_dst_adjustment(@time)
end

def min

def min
  time.min
end

def month

def month
  time.month
end

def parse_time(*args)

def parse_time(*args)
  time_klass = Time
  time_klass = Time.zone if Time.respond_to? :zone
  arg = args.shift
  if arg.is_a?(Time)
    if arg.respond_to?(:in_time_zone)
      arg.in_time_zone
    else
      arg.getlocal
    end
  elsif Object.const_defined?(:DateTime) && arg.is_a?(DateTime)
    expected_time = time_klass.local(arg.year, arg.month, arg.day, arg.hour, arg.min, arg.sec)
    expected_time += expected_time.utc_offset - rational_to_utc_offset(arg.offset)
    expected_time + compute_dst_adjustment(expected_time)
  elsif Object.const_defined?(:Date) && arg.is_a?(Date)
    time_klass.local(arg.year, arg.month, arg.day, 0, 0, 0)
  elsif args.empty? && arg.kind_of?(Integer)
    Time.now + arg
  elsif arg.nil?
    Time.now
  else
    if Time.respond_to?(:parse) && arg.is_a?(String)
      Time.parse(arg)
    else
      # we'll just assume it's a list of y/m/d/h/m/s
      year   = arg        || 2000
      month  = args.shift || 1
      day    = args.shift || 1
      hour   = args.shift || 0
      minute = args.shift || 0
      second = args.shift || 0
      time_klass.local(year, month, day, hour, minute, second)
    end
  end
end

def rational_to_utc_offset(rational)

def rational_to_utc_offset(rational)
  ((24.0 / rational.denominator) * rational.numerator) * (60 * 60)
end

def sec

def sec
  time.sec
end

def time #:nodoc:

:nodoc:
def time #:nodoc:
  if travel_offset.nil?
    @time.clone
  else
    Time.now_without_mock_time + travel_offset
  end
end

def travel_offset

def travel_offset
  @travel_offset
end

def utc_offset

def utc_offset
  time.utc_offset
end

def utc_offset_to_rational(utc_offset)

def utc_offset_to_rational(utc_offset)
  Rational(utc_offset, 24 * 60 * 60)
end

def year

def year
  time.year
end