I have an application that handles currency inputs. However, if you're in the US, you might enter a number as 12,345.67
; in France, it might be 12.345,67
.
Is there an easy way, in Rails, to adapt the currency entry to a locale?
Note that I'm not looking for display of the currency (ala number_to_currency
), I'm looking to deal with someone typing in a currency string, and converting it into a decimal.
You could give this a shot:
def string_to_float(string)
string.gsub!(/[^\d.,]/,'') # Replace all Currency Symbols, Letters and -- from the string
if string =~ /^.*[\.,]\d{1}$/ # If string ends in a single digit (e.g. ,2)
string = string + "0" # make it ,20 in order for the result to be in "cents"
end
unless string =~ /^.*[\.,]\d{2}$/ # If does not end in ,00 / .00 then
string = string + "00" # add trailing 00 to turn it into cents
end
string.gsub!(/[\.,]/,'') # Replace all (.) and (,) so the string result becomes in "cents"
string.to_f / 100 # Let to_float do the rest
end
And the test Cases:
describe Currency do
it "should mix and match" do
Currency.string_to_float("$ 1,000.50").should eql(1000.50)
Currency.string_to_float("€ 1.000,50").should eql(1000.50)
Currency.string_to_float("€ 1.000,--").should eql(1000.to_f)
Currency.string_to_float("$ 1,000.--").should eql(1000.to_f)
end
it "should strip the € sign" do
Currency.string_to_float("€1").should eql(1.to_f)
end
it "should strip the $ sign" do
Currency.string_to_float("$1").should eql(1.to_f)
end
it "should strip letter characters" do
Currency.string_to_float("a123bc2").should eql(1232.to_f)
end
it "should strip - and --" do
Currency.string_to_float("100,-").should eql(100.to_f)
Currency.string_to_float("100,--").should eql(100.to_f)
end
it "should convert the , as delimitor to a ." do
Currency.string_to_float("100,10").should eql(100.10)
end
it "should convert ignore , and . as separators" do
Currency.string_to_float("1.000,10").should eql(1000.10)
Currency.string_to_float("1,000.10").should eql(1000.10)
end
it "should be generous if you make a type in the last '0' digit" do
Currency.string_to_float("123,2").should eql(123.2)
end
We wrote this:
class String
def safe_parse
self.gsub(I18n.t("number.currency.format.unit"), '').gsub(I18n.t("number.currency.format.delimiter"), '').gsub(I18n.t("number.currency.format.separator"), '.').to_f
end
end
Of course, you will have to set the I18n.locale before using this. And it currently only converts the string to a float for the locale that was set. (In our case, if the user is on the french site, we expect the currency amount text to only have symbols and formatting pertaining to the french locale).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With