Skip to content

Commit f918fc7

Browse files
committed
add precision option for datetime string dumping
1 parent c64dbae commit f918fc7

File tree

6 files changed

+34
-7
lines changed

6 files changed

+34
-7
lines changed

dynamoid.gemspec

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ Gem::Specification.new do |spec|
2323
'Pascal Corpet',
2424
'Brian Glusman',
2525
'Peter Boling',
26-
'Andrew Konchin'
26+
'Andrew Konchin',
27+
'Ryan Foster'
2728
]
2829
2930

lib/dynamoid/dumping.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,11 @@ def format_datetime(value, options)
222222

223223
if use_string_format
224224
value_in_time_zone = Dynamoid::DynamodbTimeZone.in_time_zone(value)
225-
value_in_time_zone.iso8601
225+
if options[:iso_precision].nil?
226+
value_in_time_zone.iso8601
227+
else
228+
value_in_time_zone.iso8601(options[:iso_precision].to_i)
229+
end
226230
else
227231
unless value.respond_to?(:to_i) && value.respond_to?(:nsec)
228232
value = value.to_time

lib/dynamoid/type_casting.rb

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,14 +227,22 @@ def process(value)
227227
nil
228228
elsif value.is_a?(String)
229229
dt = begin
230+
# parse first for stricter constraint failure before attempting to parse iso for precision support
231+
# e.g. DateTime.iso8601("2018-12") is valid
230232
DateTime.parse(value)
233+
DateTime.iso8601(value)
231234
rescue StandardError
232235
nil
233236
end
234237
if dt
235-
seconds = string_utc_offset(value) || ApplicationTimeZone.utc_offset
236-
offset = seconds_to_offset(seconds)
237-
DateTime.new(dt.year, dt.mon, dt.mday, dt.hour, dt.min, dt.sec, offset)
238+
dt_has_precision = dt.to_f % 1 != 0
239+
if dt_has_precision
240+
dt.utc
241+
else
242+
seconds = string_utc_offset(value) || ApplicationTimeZone.utc_offset
243+
offset = seconds_to_offset(seconds)
244+
DateTime.new(dt.year, dt.mon, dt.mday, dt.hour, dt.min, dt.sec, offset)
245+
end
238246
end
239247
else
240248
value.to_datetime

lib/dynamoid/undumping.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ def process(value)
202202
else
203203
@options[:store_as_string]
204204
end
205-
value = DateTime.iso8601(value).to_time.to_i if use_string_format
205+
value = DateTime.iso8601(value).to_time if use_string_format
206206
ApplicationTimeZone.at(value)
207207
end
208208
end

lib/dynamoid/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# frozen_string_literal: true
22

33
module Dynamoid
4-
VERSION = '3.2.0'
4+
VERSION = '3.2.1'
55
end

spec/dynamoid/dumping_spec.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,8 @@
239239
Dynamoid.config.store_datetime_as_string = store_datetime_as_string
240240
end
241241

242+
243+
242244
it 'prioritize field option over global one' do
243245
store_datetime_as_string = Dynamoid.config.store_datetime_as_string
244246
Dynamoid.config.store_datetime_as_string = false
@@ -366,6 +368,18 @@
366368
expect(raw_attributes(obj)[:signed_up_on]).to eql('2017-09-25')
367369
end
368370

371+
it 'stores in string format with precision when :iso_precision is present' do
372+
klass = new_class do
373+
field :signed_up_on, :datetime, store_as_string: true, iso_precision: 6
374+
end
375+
376+
signed_up_on = DateTime.now.utc.iso8601(6)
377+
378+
obj = klass.create(signed_up_on: signed_up_on)
379+
380+
expect(reload(obj).signed_up_on.to_f).to eql(DateTime.iso8601(signed_up_on).to_f)
381+
end
382+
369383
it 'stores in string format when global option :store_date_as_string is true' do
370384
klass = new_class do
371385
field :signed_up_on, :date

0 commit comments

Comments
 (0)