module OCI8::BindType::Util

def self.default_timezone

def self.default_timezone
  @@default_timezone
end

def self.default_timezone=(tz)

def self.default_timezone=(tz)
  if tz != :local and tz != :utc
    raise ArgumentError, "expected :local or :utc but #{tz}"
  end
  @@default_timezone = tz
end

def array_to_datetime(ary, timezone)

def array_to_datetime(ary, timezone)
  return nil if ary.nil?
  year, month, day, hour, minute, sec, nsec, tz_hour, tz_min = ary
  sec += nsec.to_r / 1000000000 if nsec and nsec != 0
  if tz_hour and tz_min
    offset = tz_hour.to_r / 24 + tz_min.to_r / 1440
  else
    if @@default_timezone == :local
      if ::DateTime.respond_to? :local_offset
        offset = ::DateTime.local_offset # Use a method defined by active support.
      else
        # Do as active support does.
        offset = ::Time.local(2007).utc_offset.to_r / 86400
      end
    else
      offset = 0
    end
  end
  if @@datetime_has_fractional_second_bug and sec >= 59 and nsec != 0
    # convert to a DateTime via a String as a workaround
    if offset >= 0
      sign = ?+
    else
      sign = ?-
      offset = - offset;
    end
    tz_min = (offset * 1440).to_i
    tz_hour, tz_min = tz_min.divmod 60
    time_str = format("%04d-%02d-%02dT%02d:%02d:%02d.%09d%c%02d:%02d",
                      year, month, day, hour, minute, sec, nsec, sign, tz_hour, tz_min)
    ::DateTime.parse(time_str)
  else
    ::DateTime.civil(year, month, day, hour, minute, sec, offset)
  end
end

def array_to_time(ary, timezone)

after ruby 1.9.2
def array_to_time(ary, timezone)
  return nil if ary.nil?
  year, month, day, hour, minute, sec, nsec, tz_hour, tz_min = ary
  nsec ||= 0
  if timezone
    usec = (nsec == 0) ? 0 : nsec.to_r / 1000
    ::Time.send(timezone, year, month, day, hour, minute, sec, usec)
  else
    sec += nsec.to_r / 1_000_000_000 if nsec != 0
    utc_offset = tz_hour * 3600 + tz_min * 60
    ::Time.new(year, month, day, hour, minute, sec, utc_offset)
  end
end

def array_to_time(ary, timezone)

prior to ruby 1.9.2
def array_to_time(ary, timezone)
  return nil if ary.nil?
  year, month, day, hour, minute, sec, nsec, tz_hour, tz_min = ary
  nsec ||= 0
  usec = (nsec == 0) ? 0 : nsec.to_r / 1000
  begin
    if timezone
      return ::Time.send(timezone, year, month, day, hour, minute, sec, usec)
    else
      if tz_hour == 0 and tz_min == 0
        tm = ::Time.utc(year, month, day, hour, minute, sec, usec)
        # Time.utc(99, ...) returns a time object the year of which is 1999.
        # 'tm.year == year' checks such cases.
        return tm if tm.year == year
      else
        tm = ::Time.local(year, month, day, hour, minute, sec, usec)
        return tm if tm.utc_offset == tz_hour * 3600 + tz_min * 60 and tm.year == year
      end
    end
  rescue StandardError
  end
  array_to_datetime(ary, timezone)
end

def datetime_to_array(val, datatype)

def datetime_to_array(val, datatype)
  return nil if val.nil?
  # year
  year = val.year
  # month
  if val.respond_to? :mon
    month = val.mon
  elsif val.respond_to? :month
    month = val.month
  else
    raise "expect Time, Date or DateTime but #{val.class}"
  end
  # day
  if val.respond_to? :mday
    day = val.mday
  elsif val.respond_to? :day
    day = val.day
  else
    raise "expect Time, Date or DateTime but #{val.class}"
  end
  # hour
  if val.respond_to? :hour
    hour = val.hour
  else
    hour = 0
  end
  # minute
  if val.respond_to? :min
    minute = val.min
  else
    minute = 0
  end
  # second
  if val.respond_to? :sec
    sec = val.sec
  else
    sec = 0
  end
  return [year, month, day, hour, minute, sec] if datatype == :date
  # fractional second
  if val.respond_to? :sec_fraction
    fsec = (val.sec_fraction * @@datetime_fsec_base).to_i
  elsif val.respond_to? :nsec
    fsec = val.nsec
  elsif val.respond_to? :usec
    fsec = val.usec * 1000
  else
    fsec = 0
  end
  return [year, month, day, hour, minute, sec, fsec, nil, nil] if datatype == :timestamp
  # time zone
  if val.respond_to? :offset
    # DateTime
    tz_min = (val.offset * 1440).to_i
  elsif val.respond_to? :utc_offset
    # Time
    tz_min = val.utc_offset / 60
  else
    tz_hour = nil
    tz_min = nil
  end
  if tz_min
    if tz_min < 0
      tz_min = - tz_min
      tz_hour = - (tz_min / 60)
      tz_min = (tz_min % 60)
    else
      tz_hour = tz_min / 60
      tz_min = tz_min % 60
    end
  end
  [year, month, day, hour, minute, sec, fsec, tz_hour, tz_min]
end