如何使用CultureInfo来格式化已废弃的货币?

5
在dotnet中,按照特定文化方式格式化货币的推荐方法(据我所知)是:
using System.Globalization
var info = CultureInfo.GetCultureInfo("en-GB")
return string.Format(info, "{0:c}", 1234.5678)

这会返回:
 £1,234.57

然而,此处未指定具体货币。因此,如果英国将来转换为欧元,同样的方法将会返回类似以下结果:
 € 1,234.57

这刚刚发生在拉脱维亚。今年,它转换成了欧元。各种系统都包含拉脱维亚拉特和欧元的金额。我需要能够仍然打印和格式化旧货币。而且我需要确保新货币也可以处理。这种格式化不仅仅涉及符号,还涉及其位置(前面、后面、带或不带空格)和本地数字格式(小数分隔符和千位分隔符)。
我们数据库中的每个金额都有一种货币(例如EUR)和相应的文化(例如nl-NL)。欧元金额的格式化方式取决于它们是来自我们的德国办事处还是荷兰办事处。(它们都使用欧元,但会以不同的方式格式化金额)
  • dotnet提供访问旧货币的方法吗?
  • 编写格式化金额的未来可行方法是什么?
现在,我唯一能想到的方法就是将文化数据库复制到我的数据库中。

1
据我所知,.NET没有提供可以使用的传统文化。但是这似乎很简单:您的应用程序需要提供代表旧和新制度的CultureInfo对象,并适当地在它们之间进行选择。在处理货币交易时,依赖.NET自行处理是不可取的。 - Jon
@Jon:我也是这么想的。我需要在我的数据库中存储每种使用货币的CultureInfo(副本),这样如果世界发生变化,我就可以继续使用它。 - realbart
是的,它也适用于另一种情况:例如,拉脱维亚明天在当地时间00:00切换到欧元,但.NET不会在同一时刻在用户机器上自动更新。你需要提前更新你的应用程序。 - Jon
保持您的.NET Framework版本更新。那个已经完成了。 - Hans Passant
3个回答

1
当然,最简单的方法是不使用特定于区域设置的货币格式,而是将金额格式化为简单的数字,并在前缀或后缀中加上ISO货币代码。惯例。
       ------------
Sum:   ATS 1.376,00  (= EUR 100,00)

这通常在发票上发现(以区域设置de-AT为例)。

如果您想使用内置的货币格式选项,我建议用数据库中存储的货币符号替换它。也就是说,在您的currency表中,您需要将货币映射到符号:

EUR -> €
ATS -> S
...

然后你需要用数据库中的货币符号替换myCultureInfo.NumberFormat.CurrencySymbol。这样,你可以确保值不会显示错误的货币符号。


1
我还需要存储货币符号的位置(前/后,带/不带空格)和小数位数。因此,我选择将完整的NumberFormatInf数据存储在我的货币表中。 - realbart
@realbart 我假设你的货币表按照货币和区域设置(后者是用户的区域设置)存储:例如,以欧元为单位的金额在 fr-fr 和 en-us 中的格式不同(例如,小数分隔符反映客户端而不是货币)。这在一个国家有特定符号的情况下会更清晰(例如印度现在的情况),但在其他地方并不广泛使用(或被认可)。 - Richard

1
你可以创建一个自定义的CultureInfo(通过克隆并修改),该自定义使用不同的货币符号/格式(即将其NumberFormat设置为不同的NumberFormatInfo实例)。
然后根据需要将此CultureInfo传递给格式化函数。
正如问题的注释所指出的,.NET(以及Windows一般)不提供历史数据(时区也是如此,但有一个库可用)。在需要的情况下,您需要自己保存足够的数据。
记住ISO-4217货币代码在更改时不会被重复使用,因此将其与金额相结合可以正确格式化。此外,一个国家以某种方式格式化其货币金额并不意味着每个人都这样做。例如:在英国,“25法国法郎”应为“FF25.00”,而在其他地区可能是“25FF00”或“FF25,00”。(编辑:我注意到您在问题中涵盖了最后一段话。)

这(替换NumberFormatInfo)是我选择的解决方案。为该库加1分;也许我还会创建一个历史货币数据库。 - realbart

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接