tztime 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/HISTORY ADDED
@@ -0,0 +1,4 @@
1
+ == 0.1.0 2008-04-10
2
+
3
+ * 1 major enhancement:
4
+ * Initial release
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Jeremy Larkin
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,135 @@
1
+ = TZTime[http://tztime.rubyforge.org]
2
+
3
+ This library provides time zone localization and conversion with a
4
+ Time-compatible class. The time zone information is provided by the tzinfo gem.
5
+
6
+ While this library is not designed exclusively for Rails, it can be used to
7
+ make time zone aware applications in Rails. See the usage examples below to
8
+ see how you might use this in a Rails project.
9
+
10
+ === Requirements
11
+
12
+ * tztime[http://tzinfo.rubyforge.org]
13
+
14
+
15
+ === Install
16
+
17
+ * sudo gem install tztime
18
+
19
+
20
+ === Usage
21
+
22
+ This demonstrates some common uses of the library. Most of these examples
23
+ demonstrate the use of the Builder class. The Builder creates instances of
24
+ LocalTime. These can be used instead of Time instances, and they therefore have
25
+ the capabilities of the Time class. They also have a few additional methods
26
+ which may be useful. See TZTime::LocalTime for more information.
27
+
28
+ # load the tztime and tzinfo libraries
29
+ require 'tztime'
30
+
31
+ # Create a local time builder to generate and convert localized time objects
32
+ builder = TZTime::LocalTime::Builder.new('America/Los_Angeles')
33
+
34
+ # get the current date
35
+ builder.today # => 2008-04-10 00:00:00 PDT
36
+
37
+ # get the current date and time
38
+ builder.now # => 2008-04-10 15:54:52 PDT
39
+
40
+ # create a specific time value
41
+ time = builder.local(2008, 4, 10, 11, 30)
42
+ p time # => 2008-04-10 11:30:00 PDT
43
+
44
+ # convert the time into utc Time instance
45
+ time = builder.utc(2008, 4, 10, 10, 30)
46
+ p time # => 2008-04-10 07:30:00 PDT
47
+ p time.getutc # => Thu Apr 10 11:30:00 UTC 2008
48
+
49
+ # use a Time instance to create a LocalTime instance (not a conversion)
50
+ time = Time.now # => Thu Apr 10 18:55:21 -0400 2008
51
+ p builder.at(time) # => 2008-04-10 18:55:21 PDT
52
+
53
+ # use a Time instance to create a LocalTime instance converted from the time
54
+ # zone of the Time instance
55
+ time = Time.now # => Thu Apr 10 18:56:16 -0400 2008
56
+ p builder.convert(time) # => 2008-04-10 15:56:16 PDT
57
+
58
+ # convert it using a specific time zone
59
+ p builder.convert(time, 'America/Chicago') # => 2008-04-10 16:56:16 PDT
60
+
61
+ For more information about the Builder class, see TZTime::LocalTime::Builder.
62
+
63
+
64
+ === Usage in ActiveRecord
65
+
66
+ Assuming a +users+ table with this information as a minimum:
67
+
68
+ class CreateUsers < ActiveRecordMigration
69
+ def self.up
70
+ create_table :users do |t|
71
+ t.string :time_zone
72
+ t.timestamps
73
+ end
74
+ end
75
+ end
76
+
77
+
78
+ You need to require the 'tztime/active_record' library. This can be done in the
79
+ environment file or in the model that needs the time zone capabilities. Here,
80
+ we will require it in the model. Note that 'tztime' does not need to be required
81
+ seperately; 'tztime/active_record' will handle requiring it.
82
+
83
+ The User model:
84
+
85
+ require 'tztime/activerecord'
86
+
87
+ class User < ActiveRecord::Base
88
+ acts_as_time_zone
89
+ end
90
+
91
+
92
+ Create an instance and get the current date and time
93
+
94
+ user = User.create :time_zone => 'Eastern Time (US & Canada)'
95
+ user.time_zone_builder.now
96
+ user.created_at # => time in UTC
97
+ user.local_created_at # => time in EDT or EST
98
+
99
+
100
+ Use an instance to convert some other time:
101
+
102
+ entry = Entry.find(...)
103
+ user.time_zone_builder.convert(entry.created_at)
104
+ # because all times in ActiveRecord will now be in UTC, this works too
105
+ user.time_zone_builder.at_utc(entry.created_at)
106
+
107
+ === Todo
108
+
109
+ * Hook into DataMapper and Sequel ORM libraries
110
+
111
+
112
+ === License
113
+
114
+ (The MIT License)
115
+
116
+ Copyright (c) 2008 Jeremy Larkin
117
+
118
+ Permission is hereby granted, free of charge, to any person obtaining
119
+ a copy of this software and associated documentation files (the
120
+ 'Software'), to deal in the Software without restriction, including
121
+ without limitation the rights to use, copy, modify, merge, publish,
122
+ distribute, sublicense, and/or sell copies of the Software, and to
123
+ permit persons to whom the Software is furnished to do so, subject to
124
+ the following conditions:
125
+
126
+ The above copyright notice and this permission notice shall be
127
+ included in all copies or substantial portions of the Software.
128
+
129
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
130
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
131
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
132
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
133
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
134
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
135
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,5 @@
1
+ module TZTime # :nodoc:
2
+ require 'tztime/local_time'
3
+ require 'tztime/local_time/builder'
4
+ require 'tztime/time_zone_element'
5
+ end
@@ -0,0 +1,14 @@
1
+ require 'tztime'
2
+
3
+ ENV['TZ'] ||= 'UTC'
4
+ require 'activerecord' unless defined? ActiveRecord
5
+
6
+ # Adds the capability to store and use time zones in ActiveRecord models.
7
+ #
8
+ # See TZTime::ActiveRecord::Acts::LocalTime::ClassMethods
9
+ module TZTime::ActiveRecord
10
+ require 'tztime/activerecord/acts/local_time'
11
+ end
12
+
13
+ ActiveRecord::Base.send :include, TZTime::ActiveRecord::Acts::LocalTime
14
+ ActiveRecord::Base.default_timezone = :utc
@@ -0,0 +1,110 @@
1
+ module TZTime::ActiveRecord::Acts # :nodoc:
2
+ module LocalTime # :nodoc:
3
+
4
+ def self.included(into)
5
+ into.extend ClassMethods
6
+ end
7
+
8
+ # This acts provides the capabilities for storing time zones and using them
9
+ # to generate and convert times. This requires that ActiveRecord be
10
+ # configured to store times in utc. Requiring tztime/activerecord will
11
+ # configure ActiveRecord itself.
12
+ #
13
+ # This will add a composed_of property using the name provided by the
14
+ # <tt>:time_builder_accessor</tt> (defaults to <tt>:local_time_builder</tt>)
15
+ # and gets the time zone name from the <tt>:time_zone_field</tt> option
16
+ # (defaults to <tt>:time_zone</tt>).
17
+ #
18
+ # All methods that return a Time or DateTime object gain the ability to be
19
+ # localized to the timezone used by the model instance. For example, a
20
+ # <tt>created_at</tt> field value can be localized via <tt>local_created_at</tt>.
21
+ # This is not limited to field accessors; custom methods also gain this
22
+ # capability. For example:
23
+ # class Foo < ActiveRecord::Base
24
+ # acts_as_time_zone
25
+ #
26
+ # def bar
27
+ # Time.now # will be in UTC
28
+ # end
29
+ # end
30
+ #
31
+ # A localized value of <tt>bar</tt> can be accessed via <tt>local_bar</tt>.
32
+ # This value will be converted into a TZTime::LocalTime instance with the
33
+ # time zone set in the Foo instance.
34
+ #
35
+ # ==== Parameters
36
+ # options<Hash>:: See below.
37
+ #
38
+ # ==== Options
39
+ # :time_zone_field<Symbol,String>::
40
+ # The field in the database that holds the time zone name.
41
+ # Default <tt>:time_zone</tt>
42
+ #
43
+ # :time_builder_accessor<Symbol,String>::
44
+ # The name of the +composed_of+ field to create to access the local time
45
+ # builder instance.
46
+ # Default <tt>:local_time_builder</tt>
47
+ #
48
+ # === Usage
49
+ # Create a migration that includes a +time_zone+ field :
50
+ # class CreateSettings < ActiveRecordMigration
51
+ # def self.up
52
+ # create_table :settings do |t|
53
+ # t.string :time_zone
54
+ # t.timestamps
55
+ # end
56
+ # end
57
+ # end
58
+ #
59
+ # Define the Setting model:
60
+ # require 'tztime/activerecord'
61
+ #
62
+ # class Setting < ActiveRecord::Base
63
+ # acts_as_time_zone
64
+ # end
65
+ #
66
+ # Create an instance and get the current date and time
67
+ # setting = Setting.create :time_zone => 'Eastern Time (US & Canada)'
68
+ # setting.time_zone_builder.now
69
+ # setting.created_at # => time in UTC
70
+ # setting.local_created_at # => time in EDT or EST
71
+ module ClassMethods
72
+ def acts_as_local_time(options={})
73
+ options = {
74
+ :time_zone_field => :time_zone,
75
+ :time_builder_accessor => :local_time_builder
76
+ }.merge(options)
77
+
78
+ write_inheritable_attribute(:acts_as_local_time_options, options)
79
+ class_inheritable_reader :acts_as_local_time_options
80
+
81
+ if options[:time_builder_accessor] && options[:time_zone_field]
82
+ composed_of(options[:time_builder_accessor].to_sym, {
83
+ :class_name => 'TZTime::LocalTime::Builder',
84
+ :mapping => %W{#{options[:time_zone_field]} time_zone_name}
85
+ })
86
+ end
87
+
88
+ include InstanceMethods
89
+ end
90
+ end
91
+
92
+ module InstanceMethods # :nodoc:
93
+ def self.included(into)
94
+ into.alias_method_chain :method_missing, :local_time
95
+ end
96
+
97
+ def method_missing_with_local_time(name, *args, &block)
98
+ ns = name.to_s
99
+ if ns =~ /local_(.+)/ &&
100
+ value = send!($1, *args, &block)
101
+ if value.is_a?(Time) || value.is_a?(DateTime)
102
+ builder = send!(acts_as_local_time_options[:time_builder_accessor])
103
+ return builder.at_utc(value)
104
+ end
105
+ end
106
+ method_missing_without_local_time(name, *args, &block)
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,313 @@
1
+ require 'time'
2
+ require 'rubygems'
3
+ require 'tzinfo'
4
+
5
+ # A LocalTime instance wraps a Time value and a TZInfo time zone definition.
6
+ # The LocalTime class acts as a proxy to the Time value, enabling instances
7
+ # of this class to walk and talk like the Time duck.
8
+ #
9
+ # Certain methods are implemented directly in order to behave as expected
10
+ # +strftime+, +httpdate+, +rfc2822+, and +xmlschema+ are implemented to take
11
+ # proper conversions and/or time zone abbreviations into account. +getutc+
12
+ # has been implemented to create a time value converted to UTC and returned.
13
+ # (instead of returning a LocalTime instance). +to_time+, +to_date+, and
14
+ # +to_datetime+ will convert the time and return Time, Date, and DateTime
15
+ # values, respectively, converted into Universal Time. The behavior of
16
+ # +to_date+ and +to_datetime+ can be modified to not convert to UTC.
17
+ class TZTime::LocalTime
18
+ include Comparable
19
+
20
+ # The Time value wrapped by this instance.
21
+ attr_reader :time
22
+
23
+ # The TZInfo time zone definition that represents the time zone of the value
24
+ attr_reader :time_zone
25
+
26
+ # Creates a new LocalTime instance that wraps the value of +time+. +time+
27
+ # must be an instance of Time, and +time_zone must be an instance of
28
+ # TZInfo::Timezone. In most circumstances, these should not be created
29
+ # directly. Typically they will be created by a TZTime::LocalTime::Builder
30
+ # instance.
31
+ #
32
+ # ==== Parameters
33
+ # time<Time>::
34
+ # The date and time in the desired time zone. The time zone of the instance
35
+ # is ignored.
36
+ # time_zone<TZInfo::Timezone>::
37
+ # The time zone of the instance.
38
+ def initialize(time, time_zone)
39
+ raise ArgumentError, "The 'time' parameter must be an instance of Time" unless time.is_a?(Time)
40
+ raise ArgumentError, "The 'time_zone' parameter must be an instance of TZInfo::Timezone" unless time_zone.is_a?(TZInfo::Timezone)
41
+ @time = time
42
+ @time_zone = time_zone
43
+ end
44
+
45
+ # call-seq:
46
+ # time + numeric => time
47
+ #
48
+ # Addition. Adds some number of seconds (possibly fractional) to time and
49
+ # returns that value as a new time.
50
+ #
51
+ # builder = TZTime::LocalTime::Builder.new('America/New_York')
52
+ # t = builder.local(2007, 12, 16, 10, 30) # => 2007-12-16 10:30:00 EST
53
+ # t + (60 * 60 * 24) # => 2007-12-17 10:30:00 EST
54
+ def +(value)
55
+ self.class.new(@time + (value.is_a?(self.class) ? value.time : value), @time_zone)
56
+ end
57
+
58
+ # call-seq:
59
+ # time - other_time => float
60
+ # time - numeric => time
61
+ #
62
+ # Difference. Returns a new time that represents the difference between two
63
+ # times, or subtracts the given number of seconds in numeric from time.
64
+ #
65
+ # builder = TZTime::LocalTime::Builder.new('America/New_York')
66
+ # t = builder.local(2007, 12, 16, 10, 30) # => 2007-12-16 10:30:00 EST
67
+ # t2 = builder.local(2007, 12, 17, 10, 30) # => 2007-12-17 10:30:00 EST
68
+ # t2 - (60 * 60 * 24) # => 2007-12-16 10:30:00 EST
69
+ # t2 - t # => 86400
70
+ def -(value)
71
+ t = @time - (value.is_a?(self.class) ? value.time : value)
72
+ t.is_a?(Numeric) ? t : self.class.new(t, @time_zone)
73
+ end
74
+
75
+ # The full name of the time zone. This is the name used by TZInfo time zone definition
76
+ def time_zone_name
77
+ time_zone.name
78
+ end
79
+
80
+ # The +time_zone_abbreviation+ as a string
81
+ def zone
82
+ time_zone_abbreviation.to_s
83
+ end
84
+
85
+ # The offset from Universal Time in seconds
86
+ def time_zone_offset
87
+ time_zone_period.utc_total_offset
88
+ end
89
+
90
+ alias utc_offset time_zone_offset
91
+ alias gm_offset time_zone_offset
92
+
93
+ # The time zone offset as a fraction of a day (as a Rational).
94
+ def time_zone_offset_fraction
95
+ Rational(time_zone_offset, 86_400)
96
+ end
97
+
98
+ alias offset_fraction time_zone_offset_fraction
99
+
100
+ # Get the abbreviated time zone name as a Symbol. (ex :EDT, :UTC)
101
+ def time_zone_abbreviation
102
+ time_zone_period.abbreviation
103
+ end
104
+
105
+ alias time_zone_identifier time_zone_abbreviation
106
+
107
+ # Get a Time instance converted to UTC from the local time.
108
+ def getutc
109
+ @getutc ||= time_zone_period.to_utc(@time)
110
+ end
111
+
112
+ alias utc getutc
113
+ alias getgm getutc
114
+ alias to_time getutc
115
+
116
+ def getlocal
117
+ dup
118
+ end
119
+
120
+ # Convert this to a Date instance in the Universal Time. If +utc+ is
121
+ # +false+, then the value will not be converted to Universal Time first.
122
+ # Note, this can create a misleading value because Date instance cannot
123
+ # store a time zone offset.
124
+ def to_date(utc=true)
125
+ t = utc ? getutc : @time
126
+ Date.civil(t.year, t.month, t.day)
127
+ end
128
+
129
+ # Convert this to a DateTime instance in the Univeral Time. If +utc+ is
130
+ # +false+, then a DateTime with the proper time zone offset will be created.
131
+ def to_datetime(utc=true)
132
+ t = utc ? getutc : @time
133
+ DateTime.civil(t.year, t.month, t.day, t.hour, t.min, t.sec, utc ? 0 : time_zone_offset_fraction)
134
+ end
135
+
136
+ # Returns the +hour+, +min+, and +sec+ as seconds. The seconds are offset by
137
+ # the +time_zone_offset+, which can adjust the value below 0 or above 86400
138
+ # (one day).
139
+ def utc_day_seconds
140
+ local_day_seconds - time_zone_offset
141
+ end
142
+
143
+ alias gm_day_seconds gm_day_seconds
144
+
145
+ # Returns the +hour+, +min+, and +sec+ as seconds.
146
+ def local_day_seconds
147
+ @time.sec + (@time.min * 60) + (@time.hour * 3600)
148
+ end
149
+
150
+ alias day_seconds local_day_seconds
151
+
152
+ # Compare this instance's value of +time+ with another LocalTime or Time value.
153
+ def <=>(value)
154
+ getutc <=> value.getutc
155
+ end
156
+
157
+ # Determine if the time zone is in Universal Time.
158
+ def utc?
159
+ time_zone_period.abbreviation == :UTC
160
+ end
161
+
162
+ # Find the <tt>TZInfo::TimezonePeriod<?tt> for the +time_zone+
163
+ def time_zone_period
164
+ return @time_zone_period if defined?(@time_zone_period)
165
+ @time_zone_period = @time_zone.period_for_local(@time, @time.dst?)
166
+ end
167
+
168
+ # Determine if the current time is during Daylight Savings Time.
169
+ def dst?
170
+ time_zone_period.dst?
171
+ end
172
+
173
+ # Formats the time according to the directives in the given format string.
174
+ # Any text not listed as a directive will be passed through to the output string.
175
+ #
176
+ # Format meaning:
177
+ #
178
+ # %a - The abbreviated weekday name ('Sun')
179
+ # %A - The full weekday name ('Sunday')
180
+ # %b - The abbreviated month name ('Jan')
181
+ # %B - The full month name ('January')
182
+ # %c - The preferred local date and time representation
183
+ # %d - Day of the month (01..31)
184
+ # %H - Hour of the day, 24-hour clock (00..23)
185
+ # %I - Hour of the day, 12-hour clock (01..12)
186
+ # %j - Day of the year (001..366)
187
+ # %m - Month of the year (01..12)
188
+ # %M - Minute of the hour (00..59)
189
+ # %p - Meridian indicator ('AM' or 'PM')
190
+ # %P - Meridian indicator ('a' or 'p')
191
+ # %S - Second of the minute (00..60)
192
+ # %U - Week number of the current year,
193
+ # starting with the first Sunday as the first
194
+ # day of the first week (00..53)
195
+ # %W - Week number of the current year,
196
+ # starting with the first Monday as the first
197
+ # day of the first week (00..53)
198
+ # %w - Day of the week (Sunday is 0, 0..6)
199
+ # %x - Preferred representation for the date alone, no time
200
+ # %X - Preferred representation for the time alone, no date
201
+ # %y - Year without a century (00..99)
202
+ # %Y - Year with century
203
+ # %Z - Time zone name
204
+ # %% - Literal '%' character
205
+ #
206
+ # t = Time.now
207
+ # t.strftime("Printed on %m/%d/%Y") #=> "Printed on 04/09/2003"
208
+ # t.strftime("at %I:%M%p") #=> "at 08:56AM"
209
+ def strftime(string)
210
+ @time.strftime(string.
211
+ gsub(/([^%]|\A)%Z/, "\\1#{zone}").
212
+ gsub(/([^%]|\A)%P/, "\\1#{@time.hour >= 12 ? 'p' : 'a'}"))
213
+ end
214
+
215
+ # Returns a string which represents the time as rfc1123-date of HTTP-date
216
+ # defined by RFC 2616:
217
+ # day-of-week, DD month-name CCYY hh:mm:ss GMT
218
+ #
219
+ # Note that the result is always UTC (GMT).
220
+ def httpdate
221
+ getutc.httpdate
222
+ end
223
+
224
+ alias rfc1123 httpdate
225
+
226
+ # Returns a string which represents the time as date-time defined by RFC 2822:
227
+ # day-of-week, DD month-name CCYY hh:mm:ss zone
228
+ # where zone is [+-]hhmm.
229
+ #
230
+ # If +self+ is a UTC time, -0000 is used as zone.
231
+ def rfc2822
232
+ sprintf('%s, %02d %s %d %02d:%02d:%02d ',
233
+ Time::RFC2822_DAY_NAME[@time.wday],
234
+ @time.day, Time::RFC2822_MONTH_NAME[@time.mon-1], @time.year,
235
+ @time.hour, @time.min, @time.sec) +
236
+ if utc?
237
+ '-0000'
238
+ else
239
+ off = utc_offset
240
+ sign = off < 0 ? '-' : '+'
241
+ sprintf('%s%02d%02d', sign, *(off.abs / 60).divmod(60))
242
+ end
243
+ end
244
+
245
+ alias rfc822 rfc2822
246
+
247
+ # Returns a string which represents the time as dateTime defined by XML Schema:
248
+ # CCYY-MM-DDThh:mm:ssTZD
249
+ # CCYY-MM-DDThh:mm:ss.sssTZD
250
+ # where TZD is Z or [+-]hh:mm.
251
+ #
252
+ # If self is a UTC time, Z is used as TZD. [+-]hh:mm is used otherwise.
253
+ #
254
+ # +fraction_digits+ specifies a number of digits of fractional seconds. Its
255
+ # default value is 0.
256
+ def xmlschema(fraction_digits=0)
257
+ sprintf('%d-%02d-%02dT%02d:%02d:%02d',
258
+ @time.year, @time.mon, @time.day, @time.hour, @time.min, @time.sec) +
259
+ if fraction_digits.nil? || fraction_digits == 0
260
+ ''
261
+ elsif fraction_digits <= 6
262
+ '.' + sprintf('%06d', @time.usec)[0, fraction_digits]
263
+ else
264
+ '.' + sprintf('%06d', @time.usec) + '0' * (fraction_digits - 6)
265
+ end +
266
+ if utc?
267
+ 'Z'
268
+ else
269
+ off = utc_offset
270
+ sign = off < 0 ? '-' : '+'
271
+ sprintf('%s%02d:%02d', sign, *(off.abs / 60).divmod(60))
272
+ end
273
+ end
274
+
275
+ alias iso8601 xmlschema
276
+
277
+ # Converts the time into an xml-compatible string. This is the same results
278
+ # as using xmlschema, except that it can accept options. There are no options
279
+ # for the method, it is accepted for campatibility with Rails.
280
+ def to_xml(options=nil)
281
+ xmlschema
282
+ end
283
+
284
+ def to_s #:nodoc:
285
+ strftime("%Y-%m-%d %H:%M:%S %Z")
286
+ end
287
+
288
+ alias inspect to_s # :nodoc:
289
+
290
+ def dup # :nodoc:
291
+ self.class.new(@time.dup, @time_zone)
292
+ end
293
+
294
+ alias clone dup # :nodoc:
295
+
296
+ # Also check if +@time+ can respond to a method because LocalTime acts as a
297
+ # proxy to the underlying Time instance.
298
+ def respond_to?(name) # :nodoc:
299
+ super || @time.respond_to?(name)
300
+ end
301
+
302
+ # Pass on call to +@time+ unless it does not respond to the requested
303
+ # method. If +@time+ does respond and the value returned is a new Time
304
+ # value, that new value will be wrapped in a new LocalTime instance.
305
+ def method_missing(name, *args, &block) #:nodoc:
306
+ if @time.respond_to?(name)
307
+ val = @time.send(name, *args, &block)
308
+ val.is_a?(Time) ? self.class.new(val, @time_zone) : val
309
+ else
310
+ super
311
+ end
312
+ end
313
+ end