Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Customize subsecond digits when encoding DateWithTime #11464

Closed
wants to merge 1 commit into from

4 participants

@sorentwo

The subsecond fraction digits had been hardcoded to 3. This forced all timestamps to include the subsecond digits with no way to customize the value. While the subsecond format is part of the ISO8601 spec, it is not adhered to by all parsers (notably mobile clients). This adds the ability to customize the number of digits used, optionally setting them to 0 in order to eliminate the subsecond fraction entirely:

# Disable subsecond fractions
ActiveSupport::JSON::Encoding.subsecond_fraction_digits = 0

# Restore the default
ActiveSupport::JSON::Encoding.subsecond_fraction_digits = nil

Without the ability to customize the value I have no choice but to monkey patch ActiveSupport::TimeWithZone to use xmlschema. Otherwise our iOS clients chokes on every timestamp.

@sorentwo sorentwo Customize subsecond digits when encoding DateWithTime
The subsecond fraction digits had been hardcoded to 3. This forced all
timestamps to include the subsecond digits with no way to customize the
value. While the subsecond format is part of the ISO8601 spec, it is not
adhered to by all parsers (notably mobile clients). This adds the
ability to customize the number of digits used, optionally setting them
to 0 in order to eliminate the subsecond fraction entirely:

ActiveSupport::JSON::Encoding.subsecond_fraction_digits = 0
9ab168d
@robin850
Collaborator
@amro

Running into the same issue as sorentwo. Would love to see this accepted.

@pixeltrix pixeltrix was assigned
@pixeltrix pixeltrix referenced this pull request from a commit
@pixeltrix pixeltrix Add CHANGELOG entry for #11464 9484f4b
@pixeltrix
Owner

Merged in 4cfc467

@pixeltrix pixeltrix closed this
@pixeltrix
Owner

@sorentwo thanks for you contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jul 17, 2013
  1. @sorentwo

    Customize subsecond digits when encoding DateWithTime

    sorentwo authored
    The subsecond fraction digits had been hardcoded to 3. This forced all
    timestamps to include the subsecond digits with no way to customize the
    value. While the subsecond format is part of the ISO8601 spec, it is not
    adhered to by all parsers (notably mobile clients). This adds the
    ability to customize the number of digits used, optionally setting them
    to 0 in order to eliminate the subsecond fraction entirely:
    
    ActiveSupport::JSON::Encoding.subsecond_fraction_digits = 0
This page is out of date. Refresh to see the latest.
View
5 activesupport/lib/active_support/json/encoding.rb
@@ -17,6 +17,7 @@
module ActiveSupport
class << self
delegate :use_standard_json_time_format, :use_standard_json_time_format=,
+ :subsecond_fraction_digits, :subsecond_fraction_digits=,
:escape_html_entities_in_json, :escape_html_entities_in_json=,
:encode_big_decimal_as_string, :encode_big_decimal_as_string=,
:to => :'ActiveSupport::JSON::Encoding'
@@ -117,6 +118,10 @@ class << self
# to the Active Support legacy format.
attr_accessor :use_standard_json_time_format
+ # Configures the inclusion of subsecond resolution when serializing instances
+ # of ActiveSupport::TimeWithZone.
+ attr_accessor :subsecond_fraction_digits
+
# If false, serializes BigDecimal objects as numeric instead of wrapping
# them in a string.
attr_accessor :encode_big_decimal_as_string
View
3  activesupport/lib/active_support/time_with_zone.rb
@@ -154,7 +154,8 @@ def xmlschema(fraction_digits = 0)
# # => "2005/02/01 15:15:10 +0000"
def as_json(options = nil)
if ActiveSupport::JSON::Encoding.use_standard_json_time_format
- xmlschema(3)
+ digits = ActiveSupport::JSON::Encoding.subsecond_fraction_digits || 3
+ xmlschema(digits)
else
%(#{time.strftime("%Y/%m/%d %H:%M:%S")} #{formatted_offset(false)})
end
View
29 activesupport/test/core_ext/time_with_zone_test.rb
@@ -67,17 +67,25 @@ def test_zone
end
def test_to_json_with_use_standard_json_time_format_config_set_to_false
- old, ActiveSupport.use_standard_json_time_format = ActiveSupport.use_standard_json_time_format, false
- assert_equal "\"1999/12/31 19:00:00 -0500\"", ActiveSupport::JSON.encode(@twz)
- ensure
- ActiveSupport.use_standard_json_time_format = old
+ with_standard_json_time_format(false) do
+ assert_equal "\"1999/12/31 19:00:00 -0500\"", ActiveSupport::JSON.encode(@twz)
+ end
end
def test_to_json_with_use_standard_json_time_format_config_set_to_true
- old, ActiveSupport.use_standard_json_time_format = ActiveSupport.use_standard_json_time_format, true
- assert_equal "\"1999-12-31T19:00:00.000-05:00\"", ActiveSupport::JSON.encode(@twz)
+ with_standard_json_time_format(true) do
+ assert_equal "\"1999-12-31T19:00:00.000-05:00\"", ActiveSupport::JSON.encode(@twz)
+ end
+ end
+
+ def test_to_json_with_custom_subsecond_resolution
+ with_standard_json_time_format(true) do
+ ActiveSupport::JSON::Encoding.subsecond_fraction_digits = 0
+
+ assert_equal "\"1999-12-31T19:00:00-05:00\"", ActiveSupport::JSON.encode(@twz)
+ end
ensure
- ActiveSupport.use_standard_json_time_format = old
+ ActiveSupport::JSON::Encoding.subsecond_fraction_digits = nil
end
def test_to_json_when_wrapping_a_date_time
@@ -809,6 +817,13 @@ def with_env_tz(new_tz = 'US/Eastern')
ensure
old_tz ? ENV['TZ'] = old_tz : ENV.delete('TZ')
end
+
+ def with_standard_json_time_format(boolean = true)
+ old, ActiveSupport.use_standard_json_time_format = ActiveSupport.use_standard_json_time_format, boolean
+ yield
+ ensure
+ ActiveSupport.use_standard_json_time_format = old
+ end
end
class TimeWithZoneMethodsForTimeAndDateTimeTest < ActiveSupport::TestCase
Something went wrong with that request. Please try again.