Skip to content

Commit

Permalink
Adding fraction digit support, enabled by default to time parsing cor…
Browse files Browse the repository at this point in the history
…e extension
  • Loading branch information
samlown committed Mar 5, 2012
1 parent 2c5a939 commit cfa0c5a
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 9 deletions.
2 changes: 2 additions & 0 deletions lib/couchrest/model/configuration.rb
Expand Up @@ -14,11 +14,13 @@ module Configuration
add_config :environment
add_config :connection
add_config :connection_config_file
add_config :time_fraction_digits

configure do |config|
config.model_type_key = 'type' # was 'couchrest-type'
config.mass_assign_any_attribute = false
config.auto_update_design_doc = true
config.time_fraction_digits = 3

config.environment = :development
config.connection_config_file = File.join(Dir.pwd, 'config', 'couchdb.yml')
Expand Down
43 changes: 34 additions & 9 deletions lib/couchrest/model/core_extensions/time_parsing.rb
@@ -1,6 +1,7 @@
module CouchRest
module Model
module CoreExtensions

module TimeParsing

if RUBY_VERSION < "1.9.0"
Expand Down Expand Up @@ -33,34 +34,58 @@ def new(*args)
# UTC.
#
def parse_iso8601(string)
if (string =~ /(\d{4})[\-|\/](\d{2})[\-|\/](\d{2})[T|\s](\d{2}):(\d{2}):(\d{2})(Z| ?([\+|\s|\-])?(\d{2}):?(\d{2}))?/)
if (string =~ /(\d{4})[\-|\/](\d{2})[\-|\/](\d{2})[T|\s](\d{2}):(\d{2}):(\d{2}(\.\d+)?)(Z| ?([\+|\s|\-])?(\d{2}):?(\d{2}))?/)
# $1 = year
# $2 = month
# $3 = day
# $4 = hours
# $5 = minutes
# $6 = seconds
# $7 = UTC or Timezone
# $8 = time zone direction
# $9 = tz difference hours
# $10 = tz difference minutes
# $6 = seconds (with $7 for fraction)
# $8 = UTC or Timezone
# $9 = time zone direction
# $10 = tz difference hours
# $11 = tz difference minutes

if (!$7.to_s.empty? && $7 != 'Z')
new($1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i, "#{$8 == '-' ? '-' : '+'}#{$9}:#{$10}")
if $8 == 'Z' || $8.to_s.empty?
utc($1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_f)
else
utc($1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_i)
new($1.to_i, $2.to_i, $3.to_i, $4.to_i, $5.to_i, $6.to_f, "#{$9 == '-' ? '-' : '+'}#{$10}:#{$11}")
end
else
parse(string)
end
end

end

end
end
end

Time.class_eval do
extend CouchRest::Model::CoreExtensions::TimeParsing

# Override the ActiveSupport's Time#as_json method to ensure that we *always* encode
# using the iso8601 format and include fractional digits (3 by default).
#
# Including miliseconds in Time is very important for CouchDB to ensure that order
# is preserved between models created in the same second.
#
# The number of fraction digits can be set by providing it in the options:
#
# time.as_json(:fraction_digits => 6)
#
# The CouchRest Model +time_fraction_digits+ configuration option is used for the
# default fraction. Given the global nature of Time#as_json method, this configuration
# option can only be set for the whole project.
#
# CouchRest::Model::Base.time_fraction_digits = 6
#

def as_json(options = {})
fraction = options[:fraction_digits] || CouchRest::Model::Base.time_fraction_digits
xmlschema(fraction)
end

end

36 changes: 36 additions & 0 deletions spec/unit/core_extensions/time_parsing.rb
Expand Up @@ -9,6 +9,42 @@
Time.respond_to?("parse_iso8601").should be_true
end

describe "#as_json" do

it "should convert local time to JSON string" do
time = Time.new(2011, 04, 01, 19, 05, 30, "+02:00")
time.as_json.should eql("2011-04-01T19:05:30.000+02:00")
end

it "should convert utc time to JSON string" do
time = Time.utc(2011, 04, 01, 19, 05, 30)
time.as_json.should eql("2011-04-01T19:05:30.000Z")
end

it "should convert local time with fraction to JSON" do
time = Time.new(2011, 04, 01, 19, 05, 30.123, "+02:00")
time.as_json.should eql("2011-04-01T19:05:30.123+02:00")
end

it "should convert utc time with fraction to JSON" do
time = Time.utc(2011, 04, 01, 19, 05, 30.123)
time.as_json.should eql("2011-04-01T19:05:30.123Z")
end

it "should allow fraction digits" do
time = Time.utc(2011, 04, 01, 19, 05, 30.123456)
time.as_json(:fraction_digits => 6).should eql("2011-04-01T19:05:30.123456Z")
end

it "should use CouchRest::Model::Base.time_fraction_digits config option" do
CouchRest::Model::Base.time_fraction_digits = 6
time = Time.utc(2011, 04, 01, 19, 05, 30.123456)
time.as_json.should eql("2011-04-01T19:05:30.123456Z")
CouchRest::Model::Base.time_fraction_digits = 3 # Back to normal
end

end

describe ".parse_iso8601" do

describe "parsing" do
Expand Down

0 comments on commit cfa0c5a

Please sign in to comment.