Permalink
Browse files

Format numeric values based on current I18n config

Improve formatting of numeric values by making use of configured
delimiter and thousand separator.
  • Loading branch information...
1 parent 02a5df7 commit 14b3efcc5d8a60c55ddedfde9d034f07d6d65118 @carlosantoniodasilva committed Jan 25, 2012
Showing with 33 additions and 7 deletions.
  1. +1 −1 CHANGELOG.md
  2. +9 −2 README.md
  3. +9 −1 lib/i18n_alchemy/numeric_parser.rb
  4. +14 −3 test/i18n_alchemy/numeric_parser_test.rb
View
@@ -5,4 +5,4 @@
* Localize attributes=, assign_attributes, update_attribute, and update_attributes ([@tomas-stefano](https://github.com/tomas-stefano))
* Localize nested attributes ([@tomas-stefano](https://github.com/tomas-stefano))
* JRuby compatibility ([@sobrinho](https://github.com/sobrinho))
-* Format numeric values based on the current I18n number precision
+* Format numeric values based on the current I18n number precision, delimiter and thousand separator
View
@@ -50,7 +50,14 @@ Please notice that the localized proxy also formats your numeric values based on
@localized.price # => "1.30", considering a precision of 2
```
-And the same goes with date / time objects:
+And with thousand separators as well:
+
+```ruby
+@product.price = 1840.32
+@localized.price # => "1,840.32", considering separator = "," and delimiter = "."
+```
+
+Some examples with date / time objects:
```ruby
@localized.released_at = "12/31/2011"
@@ -69,7 +76,7 @@ end
The localized method quacks like ActiveRecord: you can give a hash of attributes and extra options if you want, and it will delegate everything to the object, parsing the attributes before:
```ruby
-# This will not localize released_at and other attributes, only price.
+# This will parse the attributes in the given hash.
I18n.with_locale :pt do
@localized = @product.localized(:price => "1,88")
@@ -13,7 +13,7 @@ def parse(value)
def localize(value)
if valid_for_localization?(value)
- format("%.#{precision}f", value).gsub(".", separator)
+ number_with_delimiter(format("%.#{precision}f", value))
else
value
end
@@ -44,6 +44,14 @@ def valid_for_localization?(value)
def valid_for_parsing?(value)
value.respond_to?(:gsub)
end
+
+ # Logic extracted from Rails' number_with_delimiter helper.
+ NUMBER_WITH_DELIMITER = /(\d)(?=(\d\d\d)+(?!\d))/
+ def number_with_delimiter(number)
+ parts = number.split('.')
+ parts[0].gsub!(NUMBER_WITH_DELIMITER, "\\1#{delimiter}")
+ parts.join(separator)
+ end
end
end
end
@@ -44,8 +44,13 @@ def test_localize_numeric_values
end
def test_localize_numeric_values_with_delimiters
- assert_equal "1001.20", @parser.localize(1001.2)
- assert_equal "1000001.20", @parser.localize(1_000_001.2)
+ assert_equal "123.20", @parser.localize(123.2)
+ assert_equal "999.27", @parser.localize(999.27)
+ end
+
+ def test_localize_numeric_values_with_thousand_separators
+ assert_equal "1,001.20", @parser.localize(1001.2)
+ assert_equal "1,000,001.20", @parser.localize(1_000_001.2)
end
def test_localize_numbers_based_on_current_i18n_locale
@@ -56,7 +61,13 @@ def test_localize_numbers_based_on_current_i18n_locale
def test_localize_numbers_with_delimiters_based_on_current_i18n_locale
I18n.with_locale :pt do
- assert_equal "1001,20", @parser.localize(1_001.2)
+ assert_equal "99,20", @parser.localize(99.2)
+ end
+ end
+
+ def test_localize_numbers_with_separators_based_on_current_i18n_locale
+ I18n.with_locale :pt do
+ assert_equal "1.001,20", @parser.localize(1_001.2)
end
end
end

1 comment on commit 14b3efc

Contributor

sobrinho commented on 14b3efc Jan 25, 2012

Thanks! :D

Please sign in to comment.