Skip to content

Commit

Permalink
add precision option for datetime string dumping
Browse files Browse the repository at this point in the history
  • Loading branch information
f0ster committed Jul 28, 2019
1 parent c64dbae commit f918fc7
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 7 deletions.
3 changes: 2 additions & 1 deletion dynamoid.gemspec
Expand Up @@ -23,7 +23,8 @@ Gem::Specification.new do |spec|
'Pascal Corpet',
'Brian Glusman',
'Peter Boling',
'Andrew Konchin'
'Andrew Konchin',
'Ryan Foster'
]
spec.email = ['peter.boling@gmail.com', 'brian@stellaservice.com']

Expand Down
6 changes: 5 additions & 1 deletion lib/dynamoid/dumping.rb
Expand Up @@ -222,7 +222,11 @@ def format_datetime(value, options)

if use_string_format
value_in_time_zone = Dynamoid::DynamodbTimeZone.in_time_zone(value)
value_in_time_zone.iso8601
if options[:iso_precision].nil?
value_in_time_zone.iso8601
else
value_in_time_zone.iso8601(options[:iso_precision].to_i)
end
else
unless value.respond_to?(:to_i) && value.respond_to?(:nsec)
value = value.to_time
Expand Down
14 changes: 11 additions & 3 deletions lib/dynamoid/type_casting.rb
Expand Up @@ -227,14 +227,22 @@ def process(value)
nil
elsif value.is_a?(String)
dt = begin
# parse first for stricter constraint failure before attempting to parse iso for precision support
# e.g. DateTime.iso8601("2018-12") is valid
DateTime.parse(value)
DateTime.iso8601(value)
rescue StandardError
nil
end
if dt
seconds = string_utc_offset(value) || ApplicationTimeZone.utc_offset
offset = seconds_to_offset(seconds)
DateTime.new(dt.year, dt.mon, dt.mday, dt.hour, dt.min, dt.sec, offset)
dt_has_precision = dt.to_f % 1 != 0
if dt_has_precision
dt.utc
else
seconds = string_utc_offset(value) || ApplicationTimeZone.utc_offset
offset = seconds_to_offset(seconds)
DateTime.new(dt.year, dt.mon, dt.mday, dt.hour, dt.min, dt.sec, offset)
end
end
else
value.to_datetime
Expand Down
2 changes: 1 addition & 1 deletion lib/dynamoid/undumping.rb
Expand Up @@ -202,7 +202,7 @@ def process(value)
else
@options[:store_as_string]
end
value = DateTime.iso8601(value).to_time.to_i if use_string_format
value = DateTime.iso8601(value).to_time if use_string_format
ApplicationTimeZone.at(value)
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/dynamoid/version.rb
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module Dynamoid
VERSION = '3.2.0'
VERSION = '3.2.1'
end
14 changes: 14 additions & 0 deletions spec/dynamoid/dumping_spec.rb
Expand Up @@ -239,6 +239,8 @@
Dynamoid.config.store_datetime_as_string = store_datetime_as_string
end



it 'prioritize field option over global one' do
store_datetime_as_string = Dynamoid.config.store_datetime_as_string
Dynamoid.config.store_datetime_as_string = false
Expand Down Expand Up @@ -366,6 +368,18 @@
expect(raw_attributes(obj)[:signed_up_on]).to eql('2017-09-25')
end

it 'stores in string format with precision when :iso_precision is present' do
klass = new_class do
field :signed_up_on, :datetime, store_as_string: true, iso_precision: 6
end

signed_up_on = DateTime.now.utc.iso8601(6)

obj = klass.create(signed_up_on: signed_up_on)

expect(reload(obj).signed_up_on.to_f).to eql(DateTime.iso8601(signed_up_on).to_f)
end

it 'stores in string format when global option :store_date_as_string is true' do
klass = new_class do
field :signed_up_on, :date
Expand Down

0 comments on commit f918fc7

Please sign in to comment.