1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
#--
# Copyright (c) 2008-2013 Philip Ross
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#++
require 'date'
require 'rational' unless defined?(Rational)
module TZInfo
# Methods to support different versions of Ruby.
#
# @private
module RubyCoreSupport #:nodoc:
# Use Rational.new! for performance reasons in Ruby 1.8.
# This has been removed from 1.9, but Rational performs better.
if Rational.respond_to? :new!
def self.rational_new!(numerator, denominator = 1)
Rational.new!(numerator, denominator)
end
else
def self.rational_new!(numerator, denominator = 1)
Rational(numerator, denominator)
end
end
# Ruby 1.8.6 introduced new! and deprecated new0.
# Ruby 1.9.0 removed new0.
# Ruby trunk revision 31668 removed the new! method.
# Still support new0 for better performance on older versions of Ruby (new0 indicates
# that the rational has already been reduced to its lowest terms).
# Fallback to jd with conversion from ajd if new! and new0 are unavailable.
if DateTime.respond_to? :new!
def self.datetime_new!(ajd = 0, of = 0, sg = Date::ITALY)
DateTime.new!(ajd, of, sg)
end
elsif DateTime.respond_to? :new0
def self.datetime_new!(ajd = 0, of = 0, sg = Date::ITALY)
DateTime.new0(ajd, of, sg)
end
else
HALF_DAYS_IN_DAY = rational_new!(1, 2)
def self.datetime_new!(ajd = 0, of = 0, sg = Date::ITALY)
# Convert from an Astronomical Julian Day number to a civil Julian Day number.
jd = ajd + of + HALF_DAYS_IN_DAY
# Ruby trunk revision 31862 changed the behaviour of DateTime.jd so that it will no
# longer accept a fractional civil Julian Day number if further arguments are specified.
# Calculate the hours, minutes and seconds to pass to jd.
jd_i = jd.to_i
jd_i -= 1 if jd < 0
hours = (jd - jd_i) * 24
hours_i = hours.to_i
minutes = (hours - hours_i) * 60
minutes_i = minutes.to_i
seconds = (minutes - minutes_i) * 60
DateTime.jd(jd_i, hours_i, minutes_i, seconds, of, sg)
end
end
# DateTime in Ruby 1.8.6 doesn't consider times within the 60th second to be
# valid. When attempting to specify such a DateTime, subtract the fractional
# part and then add it back later
if Date.respond_to?(:valid_time?) && !Date.valid_time?(0, 0, rational_new!(59001, 1000)) # 0:0:59.001
def self.datetime_new(y=-4712, m=1, d=1, h=0, min=0, s=0, of=0, sg=Date::ITALY)
if !s.kind_of?(Integer) && s > 59
dt = DateTime.new(y, m, d, h, min, 59, of, sg)
dt + (s - 59) / 86400
else
DateTime.new(y, m, d, h, min, s, of, sg)
end
end
else
def self.datetime_new(y=-4712, m=1, d=1, h=0, min=0, s=0, of=0, sg=Date::ITALY)
DateTime.new(y, m, d, h, min, s, of, sg)
end
end
# Returns true if Time on the runtime platform supports Times defined
# by negative 32-bit timestamps, otherwise false.
begin
Time.at(-1)
Time.at(-2147483648)
def self.time_supports_negative
true
end
rescue ArgumentError
def self.time_supports_negative
false
end
end
# Returns true if Time on the runtime platform supports Times defined by
# 64-bit timestamps, otherwise false.
begin
Time.at(-2147483649)
Time.at(2147483648)
def self.time_supports_64bit
true
end
rescue RangeError
def self.time_supports_64bit
false
end
end
# Return the result of Time#nsec if it exists, otherwise return the
# result of Time#usec * 1000.
if Time.method_defined?(:nsec)
def self.time_nsec(time)
time.nsec
end
else
def self.time_nsec(time)
time.usec * 1000
end
end
# Call String#force_encoding if this version of Ruby has encoding support
# otherwise treat as a no-op.
if String.method_defined?(:force_encoding)
def self.force_encoding(str, encoding)
str.force_encoding(encoding)
end
else
def self.force_encoding(str, encoding)
str
end
end
# Wrapper for File.open that supports passing hash options for specifying
# encodings on Ruby 1.9+. The options are ignored on earlier versions of
# Ruby.
if RUBY_VERSION =~ /\A1\.[0-8]\./
def self.open_file(file_name, mode, opts, &block)
File.open(file_name, mode, &block)
end
else
def self.open_file(file_name, mode, opts, &block)
File.open(file_name, mode, opts, &block)
end
end
end
end
|