diff --git a/lib/tzinfo/time_or_datetime.rb b/lib/tzinfo/time_or_datetime.rb index 91938b4e..e36a0521 100644 --- a/lib/tzinfo/time_or_datetime.rb +++ b/lib/tzinfo/time_or_datetime.rb @@ -9,8 +9,8 @@ class TimeOrDateTime include Comparable # Constructs a new TimeOrDateTime. timeOrDateTime can be a Time, DateTime - # or Integer. If using a Time or DateTime, any time zone information - # is ignored. + # or Integer. The UTC offset from Time or DateTime instances is ignored + # unless ignore_offset is set to false. def initialize(timeOrDateTime, ignore_offset = true) @time = nil @datetime = nil @@ -198,8 +198,7 @@ def usec end end - # Returns utc offset of original value _in seconds_ (or 0 if original - # value was integer timestamp). + # Returns the UTC offset of this TimeOrDateTime in seconds. def offset if @time @time.utc_offset @@ -270,20 +269,24 @@ def -(seconds) self + (-seconds) end - # Converts TimeOrDateTime to new UTC offset. - # Considers original value's UTC offset wisely. - def to_offset(seconds) + # For TimeOrDateTime instances based on Time or DateTime values, returns a + # new TimeOrDateTime created by adjusting the UTC offset to the given + # offset in seconds. + # + # For TimeOrDateTime instances based on Integer timestamps, returns a new + # TimeOrDateTime created by adding the given offset to the timestamp. + def to_offset(offset) if @orig.is_a?(DateTime) - off = OffsetRationals.rational_for_offset(seconds) + off = OffsetRationals.rational_for_offset(offset) TimeOrDateTime.new(@orig.new_offset(off), false) elsif @orig.is_a?(Time) - time = @time.getutc + seconds + time = @time.getutc + offset nsec_part = Rational(time.nsec, 1_000_000_000) - time = Time.new(time.year, time.mon, time.mday, time.hour, time.min, time.sec + nsec_part, seconds) + time = Time.new(time.year, time.mon, time.mday, time.hour, time.min, time.sec + nsec_part, offset) TimeOrDateTime.new(time, false) else # Integer: fallback to "just shift timestamp" - TimeOrDateTime.new(@orig + seconds) + TimeOrDateTime.new(@orig + offset) end end @@ -311,11 +314,10 @@ def hash # will be constructed and the value passed to wrap will be used when # calling the block. # - # Optional ignore_offset second parameter (defaults to true) controls - # whether timezone/UTC offset of input value will be considered or - # ignored completely (in a latter case `2016-06-01 12:30:50 +03:00` - # and `2016-06-01 12:30:50 GMT` would be wrapped into exactly the - # same `TimeOrDateTime` object). + # The UTC offset from Time or DateTime instances is ignored unless + # ignore_offset is set to false (for example, 2016-06-01 12:30:50 +03:00 + # and 2016-06-01 12:30:50 GMT would be wrapped into exactly the same + # TimeOrDateTime object when ignore_offset is true). def self.wrap(timeOrDateTime, ignore_offset = true) t = timeOrDateTime.is_a?(TimeOrDateTime) ? timeOrDateTime : TimeOrDateTime.new(timeOrDateTime, ignore_offset) diff --git a/lib/tzinfo/timezone.rb b/lib/tzinfo/timezone.rb index 2a691dbb..7d2c8cbb 100644 --- a/lib/tzinfo/timezone.rb +++ b/lib/tzinfo/timezone.rb @@ -266,14 +266,20 @@ def friendly_identifier(skip_first_part = false) # Returns the TimezonePeriod for the given UTC time. utc can either be # a DateTime, Time or integer timestamp (Time.to_i). Any timezone - # information in utc is ignored (it is treated as a UTC time). + # information in utc is ignored (it is treated as a UTC time). Use the + # period_for method instead if the the UTC offset of the time needs to be + # considered. def period_for_utc(utc) raise_unknown_timezone end # Returns the set of TimezonePeriod instances that are valid for the given - # local time as an array. If you just want a single period, use - # period_for_local instead and specify how ambiguities should be resolved. + # local time as an array. Any timezone information in local is ignored + # (it is treated as a time in the current timezone). + # + # If you just want a single period, use period_for_local instead and specify + # how ambiguities should be resolved. + # # Returns an empty array if no periods are found for the given time. def periods_for_local(local) raise_unknown_timezone @@ -347,7 +353,8 @@ def canonical_zone # Returns the TimezonePeriod for the given local time. local can either be # a DateTime, Time or integer timestamp (Time.to_i). Any timezone # information in local is ignored (it is treated as a time in the current - # timezone). + # timezone). Use the period_for method instead if the the UTC offset of the + # time needs to be considered. # # Warning: There are local times that have no equivalent UTC times (e.g. # in the transition from standard time to daylight savings time). There are @@ -418,32 +425,32 @@ def period_for_local(local, dst = Timezone.default_dst) end end - # Returns the TimezonePeriod for the given local time. local can either be - # a DateTime, Time or integer timestamp (Time.to_i). Unlike `period_for_local`, - # actually considers timezone information of local, thus eliminating - # all complexities about AmbiguousTime. + # Returns the TimezonePeriod for the given time. time can either be + # a DateTime, Time or integer timestamp (Time.to_i). # - def period_for(local) - # FIXME: maybe define TimeOrDateTime#to_utc as a synonym for #to_offset(0)?.. - period_for_utc(TimeOrDateTime.wrap(local, false).to_offset(0)) + # Unlike period_for_local and period_for_utc, period_for considers the UTC + # offset of the given time. + def period_for(time) + period_for_utc(TimeOrDateTime.wrap(time, false).to_offset(0)) end # Converts a time in UTC to the local timezone. utc can either be # a DateTime, Time or timestamp (Time.to_i). The returned time has the same # type as utc. Any timezone information in utc is ignored (it is treated as - # a UTC time). + # a UTC time). Use the to_local method instead if the the UTC offset of the + # time needs to be considered. def utc_to_local(utc) TimeOrDateTime.wrap(utc) {|wrapped| period_for_utc(wrapped).to_local(wrapped) } end - # Converts a time in some local timezone to another local timezone. - # another_local can either be a DateTime, Time or timestamp (Time.to_i). + # Converts a time to the local timezone. time can either be a DateTime, Time + # or timestamp (Time.to_i). # - # Considers timezone of another_local. - def to_local(another_local) - TimeOrDateTime.wrap(another_local, false) {|wrapped| + # Unlike utc_to_local, to_local considers the UTC offset of the given time. + def to_local(time) + TimeOrDateTime.wrap(time, false) {|wrapped| period_for(wrapped).to_local(wrapped) } end