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)
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)
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