Class: TZTime::LocalTime

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/tztime/local_time.rb

Overview

A LocalTime instance wraps a Time value and a TZInfo time zone definition. The LocalTime class acts as a proxy to the Time value, enabling instances of this class to walk and talk like the Time duck.

Certain methods are implemented directly in order to behave as expected strftime, httpdate, rfc2822, and xmlschema are implemented to take proper conversions and/or time zone abbreviations into account. getutc has been implemented to create a time value converted to UTC and returned. (instead of returning a LocalTime instance). to_time, to_date, and to_datetime will convert the time and return Time, Date, and DateTime values, respectively, converted into Universal Time. The behavior of to_date and to_datetime can be modified to not convert to UTC.

Defined Under Namespace

Classes: Builder

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(time, time_zone) ⇒ LocalTime

Creates a new LocalTime instance that wraps the value of time. time must be an instance of Time, and +time_zone must be an instance of TZInfo::Timezone. In most circumstances, these should not be created directly. Typically they will be created by a TZTime::LocalTime::Builder instance.

Parameters

time<Time>

The date and time in the desired time zone. The time zone of the instance is ignored.

time_zone<TZInfo::Timezone>

The time zone of the instance.

Raises:

  • (ArgumentError)


38
39
40
41
42
43
# File 'lib/tztime/local_time.rb', line 38

def initialize(time, time_zone)
  raise ArgumentError, "The 'time' parameter must be an instance of Time" unless time.is_a?(Time)
  raise ArgumentError, "The 'time_zone' parameter must be an instance of TZInfo::Timezone" unless time_zone.is_a?(TZInfo::Timezone)
  @time = time
  @time_zone = time_zone
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object

Pass on call to @time unless it does not respond to the requested method. If @time does respond and the value returned is a new Time value, that new value will be wrapped in a new LocalTime instance.



305
306
307
308
309
310
311
312
# File 'lib/tztime/local_time.rb', line 305

def method_missing(name, *args, &block) #:nodoc:
  if @time.respond_to?(name)
    val = @time.send(name, *args, &block)
    val.is_a?(Time) ? self.class.new(val, @time_zone) : val
  else
    super
  end
end

Instance Attribute Details

#timeObject (readonly)

The Time value wrapped by this instance.



21
22
23
# File 'lib/tztime/local_time.rb', line 21

def time
  @time
end

#time_zoneObject (readonly)

The TZInfo time zone definition that represents the time zone of the value



24
25
26
# File 'lib/tztime/local_time.rb', line 24

def time_zone
  @time_zone
end

Instance Method Details

#+(value) ⇒ Object

call-seq:

time + numeric => time

Addition. Adds some number of seconds (possibly fractional) to time and returns that value as a new time.

builder = TZTime::LocalTime::Builder.new('America/New_York')
t = builder.local(2007, 12, 16, 10, 30) # => 2007-12-16 10:30:00 EST
t + (60 * 60 * 24)                      # => 2007-12-17 10:30:00 EST


54
55
56
# File 'lib/tztime/local_time.rb', line 54

def +(value)
  self.class.new(@time + (value.is_a?(self.class) ? value.time : value), @time_zone)
end

#-(value) ⇒ Object

call-seq:

time - other_time => float
time - numeric => time

Difference. Returns a new time that represents the difference between two times, or subtracts the given number of seconds in numeric from time.

builder = TZTime::LocalTime::Builder.new('America/New_York')
t = builder.local(2007, 12, 16, 10, 30)  # => 2007-12-16 10:30:00 EST
t2 = builder.local(2007, 12, 17, 10, 30) # => 2007-12-17 10:30:00 EST
t2 - (60 * 60 * 24)                      # => 2007-12-16 10:30:00 EST
t2 - t                                   # => 86400


70
71
72
73
# File 'lib/tztime/local_time.rb', line 70

def -(value)
  t = @time - (value.is_a?(self.class) ? value.time : value)
  t.is_a?(Numeric) ? t : self.class.new(t, @time_zone)
end

#<=>(value) ⇒ Object

Compare this instance’s value of time with another LocalTime or Time value.



153
154
155
# File 'lib/tztime/local_time.rb', line 153

def <=>(value)
  getutc <=> value.getutc
end

#dst?Boolean

Determine if the current time is during Daylight Savings Time.

Returns:

  • (Boolean)


169
170
171
# File 'lib/tztime/local_time.rb', line 169

def dst?
  time_zone_period.dst?
end

#dupObject Also known as: clone

:nodoc:



290
291
292
# File 'lib/tztime/local_time.rb', line 290

def dup # :nodoc:
  self.class.new(@time.dup, @time_zone)
end

#getlocalObject



116
117
118
# File 'lib/tztime/local_time.rb', line 116

def getlocal
  dup
end

#getutcObject Also known as: utc, getgm, to_time

Get a Time instance converted to UTC from the local time.



108
109
110
# File 'lib/tztime/local_time.rb', line 108

def getutc
  @getutc ||= time_zone_period.to_utc(@time)
end

#httpdateObject Also known as: rfc1123

Returns a string which represents the time as rfc1123-date of HTTP-date defined by RFC 2616:

day-of-week, DD month-name CCYY hh:mm:ss GMT

Note that the result is always UTC (GMT).



220
221
222
# File 'lib/tztime/local_time.rb', line 220

def httpdate
  getutc.httpdate
end

#local_day_secondsObject Also known as: day_seconds

Returns the hour, min, and sec as seconds.



146
147
148
# File 'lib/tztime/local_time.rb', line 146

def local_day_seconds
  @time.sec + (@time.min * 60) + (@time.hour * 3600)
end

#respond_to?(name) ⇒ Boolean

Also check if @time can respond to a method because LocalTime acts as a proxy to the underlying Time instance.

Returns:

  • (Boolean)


298
299
300
# File 'lib/tztime/local_time.rb', line 298

def respond_to?(name) # :nodoc:
  super || @time.respond_to?(name)
end

#rfc2822Object Also known as: rfc822

Returns a string which represents the time as date-time defined by RFC 2822:

day-of-week, DD month-name CCYY hh:mm:ss zone

where zone is [+-]hhmm.

If self is a UTC time, -0000 is used as zone.



231
232
233
234
235
236
237
238
239
240
241
242
243
# File 'lib/tztime/local_time.rb', line 231

def rfc2822
  sprintf('%s, %02d %s %d %02d:%02d:%02d ',
    Time::RFC2822_DAY_NAME[@time.wday],
    @time.day, Time::RFC2822_MONTH_NAME[@time.mon-1], @time.year,
    @time.hour, @time.min, @time.sec) +
  if utc?
    '-0000'
  else
    off = utc_offset
    sign = off < 0 ? '-' : '+'
    sprintf('%s%02d%02d', sign, *(off.abs / 60).divmod(60))
  end
end

#strftime(string) ⇒ Object

Formats the time according to the directives in the given format string. Any text not listed as a directive will be passed through to the output string.

Format meaning:

%a - The abbreviated weekday name ('Sun')
%A - The  full  weekday  name ('Sunday')
%b - The abbreviated month name ('Jan')
%B - The  full  month  name ('January')
%c - The preferred local date and time representation
%d - Day of the month (01..31)
%H - Hour of the day, 24-hour clock (00..23)
%I - Hour of the day, 12-hour clock (01..12)
%j - Day of the year (001..366)
%m - Month of the year (01..12)
%M - Minute of the hour (00..59)
%p - Meridian indicator ('AM' or 'PM')
%P - Meridian indicator ('a' or 'p')
%S - Second of the minute (00..60)
%U - Week  number  of the current year,
        starting with the first Sunday as the first
        day of the first week (00..53)
%W - Week  number  of the current year,
        starting with the first Monday as the first
        day of the first week (00..53)
%w - Day of the week (Sunday is 0, 0..6)
%x - Preferred representation for the date alone, no time
%X - Preferred representation for the time alone, no date
%y - Year without a century (00..99)
%Y - Year with century
%Z - Time zone name
%% - Literal '%' character

 t = Time.now
 t.strftime("Printed on %m/%d/%Y")   #=> "Printed on 04/09/2003"
 t.strftime("at %I:%M%p")            #=> "at 08:56AM"


209
210
211
212
213
# File 'lib/tztime/local_time.rb', line 209

def strftime(string)
  @time.strftime(string.
   gsub(/([^%]|\A)%Z/, "\\1#{zone}").
   gsub(/([^%]|\A)%P/, "\\1#{@time.hour >= 12 ? 'p' : 'a'}"))
end

#time_zone_abbreviationObject Also known as: time_zone_identifier

Get the abbreviated time zone name as a Symbol. (ex :EDT, :UTC)



101
102
103
# File 'lib/tztime/local_time.rb', line 101

def time_zone_abbreviation
  time_zone_period.abbreviation
end

#time_zone_nameObject

The full name of the time zone. This is the name used by TZInfo time zone definition



76
77
78
# File 'lib/tztime/local_time.rb', line 76

def time_zone_name
  time_zone.name
end

#time_zone_offsetObject Also known as: utc_offset, gm_offset

The offset from Universal Time in seconds



86
87
88
# File 'lib/tztime/local_time.rb', line 86

def time_zone_offset
  time_zone_period.utc_total_offset
end

#time_zone_offset_fractionObject Also known as: offset_fraction

The time zone offset as a fraction of a day (as a Rational).



94
95
96
# File 'lib/tztime/local_time.rb', line 94

def time_zone_offset_fraction
  Rational(time_zone_offset, 86_400)
end

#time_zone_periodObject

Find the <tt>TZInfo::TimezonePeriod<?tt> for the time_zone



163
164
165
166
# File 'lib/tztime/local_time.rb', line 163

def time_zone_period
  return @time_zone_period if defined?(@time_zone_period)
  @time_zone_period = @time_zone.period_for_local(@time, @time.dst?)
end

#to_date(utc = true) ⇒ Object

Convert this to a Date instance in the Universal Time. If utc is false, then the value will not be converted to Universal Time first. Note, this can create a misleading value because Date instance cannot store a time zone offset.



124
125
126
127
# File 'lib/tztime/local_time.rb', line 124

def to_date(utc=true)
  t = utc ? getutc : @time
  Date.civil(t.year, t.month, t.day)
end

#to_datetime(utc = true) ⇒ Object

Convert this to a DateTime instance in the Univeral Time. If utc is false, then a DateTime with the proper time zone offset will be created.



131
132
133
134
# File 'lib/tztime/local_time.rb', line 131

def to_datetime(utc=true)
  t = utc ? getutc : @time
  DateTime.civil(t.year, t.month, t.day, t.hour, t.min, t.sec, utc ? 0 : time_zone_offset_fraction)
end

#to_sObject Also known as: inspect

:nodoc:



284
285
286
# File 'lib/tztime/local_time.rb', line 284

def to_s #:nodoc:
  strftime("%Y-%m-%d %H:%M:%S %Z")
end

#to_xml(options = nil) ⇒ Object

Converts the time into an xml-compatible string. This is the same results as using xmlschema, except that it can accept options. There are no options for the method, it is accepted for campatibility with Rails.



280
281
282
# File 'lib/tztime/local_time.rb', line 280

def to_xml(options=nil)
  xmlschema
end

#utc?Boolean

Determine if the time zone is in Universal Time.

Returns:

  • (Boolean)


158
159
160
# File 'lib/tztime/local_time.rb', line 158

def utc?
  time_zone_period.abbreviation == :UTC
end

#utc_day_secondsObject

Returns the hour, min, and sec as seconds. The seconds are offset by the time_zone_offset, which can adjust the value below 0 or above 86400 (one day).



139
140
141
# File 'lib/tztime/local_time.rb', line 139

def utc_day_seconds
  local_day_seconds - time_zone_offset
end

#xmlschema(fraction_digits = 0) ⇒ Object Also known as: iso8601

Returns a string which represents the time as dateTime defined by XML Schema:

CCYY-MM-DDThh:mm:ssTZD
CCYY-MM-DDThh:mm:ss.sssTZD

where TZD is Z or [+-]hh:mm.

If self is a UTC time, Z is used as TZD. [+-]hh:mm is used otherwise.

fraction_digits specifies a number of digits of fractional seconds. Its default value is 0.



256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
# File 'lib/tztime/local_time.rb', line 256

def xmlschema(fraction_digits=0)
  sprintf('%d-%02d-%02dT%02d:%02d:%02d',
    @time.year, @time.mon, @time.day, @time.hour, @time.min, @time.sec) +
  if fraction_digits.nil? || fraction_digits == 0
    ''
  elsif fraction_digits <= 6
    '.' + sprintf('%06d', @time.usec)[0, fraction_digits]
  else
    '.' + sprintf('%06d', @time.usec) + '0' * (fraction_digits - 6)
  end +
  if utc?
    'Z'
  else
    off = utc_offset
    sign = off < 0 ? '-' : '+'
    sprintf('%s%02d:%02d', sign, *(off.abs / 60).divmod(60))
  end
end

#zoneObject

The time_zone_abbreviation as a string



81
82
83
# File 'lib/tztime/local_time.rb', line 81

def zone
  time_zone_abbreviation.to_s
end