LC_MONETARY formatting

C

Colin Fox

Hi, all.

This feels like a stupid question to me, but I've scoured the Internet
(yes, the whole thing! :) and I can't find a single example of using the
locale module to format money.

So I have:

cash = 12345.6

and the locale is set to "en_CA" (though that doesn't matter, really).

I would like to be able to print "$12,345.60"

Is there a format string, or function, or *something* that will take
advantage of the monetary formatting info in the locale object? Or did
they provide all that formatting information just so that I have to write
it myself?

The only docs on using the locale object contain a single example of
comparing two strings. It would sure be nice to see examples of each of
the locale features.

Any help would be GREATLY appreciated!

Thanks,
cf
 
M

Martin v. Loewis

Colin said:
So I have:

cash = 12345.6

and the locale is set to "en_CA" (though that doesn't matter, really).

I would like to be able to print "$12,345.60"

Is there a format string, or function, or *something* that will take
advantage of the monetary formatting info in the locale object?
No.

Or did
they provide all that formatting information just so that I have to write
it myself?

Yes. Use locale.localeconv() to find the relevant parameters.

Make sure you understand that using 'currency_symbol' presents a problem
if the amount you have is already in some currency. Printing the same
value in different locales using the naïve formatting algorithm is
likely to produce incorrect results, as you have to apply some exchange
rate, which varies from day to day, and from trading place to trading
place.

IOW, LC_MONETARY is useless for financial applications - if the amount
is in ¤, using the locale's currency symbol would be wrong.

Regards,
Martin
 
C

Colin Fox

Colin Fox wrote:

No.

I can't believe that I'm the first person who ever wanted to print a
number as a currency value. Why go to the great lengths of what's provided
in localeconv(), only to leave it up to every single programmer to
re-implement the solution? What a waste of time and effort!

I can't see any reason not to provide a monetary converter within locale,
particularly when it's obviously got all the info it needs.
IOW, LC_MONETARY is useless for financial applications - if the amount
is in ¤, using the locale's currency symbol would be wrong.

That's true whether you use LC_MONETARY or not. Unless you know the units
your number is in, you can't assign a symbol to it. In my case, I have
numbers that are always in either Canadian or US dollars, so the dollar
sign is fine, and the thousands-separator value is fine.

cf
 
F

Frank Bechmann

this

http://oss.software.ibm.com/icu/

is - as far as I know - *the* OS catch-all project for
encoding-conversion and localisation tasks. It's written in C++, has a
C wrapper and Java's functionality on these topics is based on ICU. I
don't know whether there's a python wrapper for it, but IIRC the
gnue-project (which is mainly written in Python) uses ICU.

but as stated above often in commercial applications the problem is
not the currency formatting but to provide the complete information of
amount, source currency and target currency throughout the complete
flow of the program.
 
S

Serge Orlov

Colin Fox said:
I can't believe that I'm the first person who ever wanted to print a
number as a currency value. Why go to the great lengths of what's provided
in localeconv(), only to leave it up to every single programmer to
re-implement the solution? What a waste of time and effort!

Compared to the effort of all humanity to move forward the waste
of time and effort is dwarf said:
I can't see any reason not to provide a monetary converter within locale,
particularly when it's obviously got all the info it needs.

It's not as simple as you think. The proper way to do it is to have locale
aware money type.
That's true whether you use LC_MONETARY or not. Unless you know the units
your number is in, you can't assign a symbol to it.

That's why LC_MONETARY (strfmon) is broken. Have you read strfmon manual?
In my case, I have
numbers that are always in either Canadian or US dollars, so the dollar
sign is fine, and the thousands-separator value is fine.

You should have money class. It should be a subclass of FixedPoint class.
If you want to deal with Canadian or US dollars only it's as simple as:
class Dollars(FixedPoint):
def __init__(self,amount):
super(Dollars,self).__init__(amount)
def __str__(self):
if self < 0:
return locale.format("-$%.2f",-self,True)
else:
return locale.format("$%.2f",self,True)


No warranty, of course, that it works and fulfills all your needs.'$1,000,000,000,000.00'

-- Serge.
 
?

=?ISO-8859-15?Q?=22Martin_v=2E_L=F6wis=22?=

Colin said:
I can't believe that I'm the first person who ever wanted to print a
number as a currency value. Why go to the great lengths of what's provided
in localeconv(), only to leave it up to every single programmer to
re-implement the solution? What a waste of time and effort!

As Serge points out, C has strfmon. For Python, better start believing
that you are the first person who ever wanted to print a number as a
currency value in a locale-dependent way.

Feel free to contribute patches if you think this should be provided
out of the box.

Regards,
Martin
 
C

Colin Fox

You should have money class. It should be a subclass of FixedPoint class.
If you want to deal with Canadian or US dollars only it's as simple as:
class Dollars(FixedPoint):
def __init__(self,amount):
super(Dollars,self).__init__(amount)
def __str__(self):
if self < 0:
return locale.format("-$%.2f",-self,True)
else:
return locale.format("$%.2f",self,True)


No warranty, of course, that it works and fulfills all your needs.
'$1,000,000,000,000.00'

Thanks, the locale.format() function indeed does what I need. However, my
understanding of it is that it uses the LC_NUMERIC locale info, rather
than the LC_MONETARY. For my purposes, this is certainly sufficient.

I'd like to use a class, but since this is part of a Zope application,
that's a little difficult (and overkill for this particular need).

It would be nice if we could have something like:
locale.format("%m",1000000,True,locale.LC_MONETARY)
though as is indicated in the strfmon docs, it wouldn't be quite so simple
(taking into account the different types of currency markers, padding,
spacing, etc).

cf
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,175
Messages
2,570,942
Members
47,490
Latest member
Finplus

Latest Threads

Top