2012-11-13 31 views
6

Tôi có bảng phí với số tiền và mã đơn vị tiền tệ (USD, JPY, CAD, EUR, v.v.) và đang tìm cách dễ nhất để định dạng đúng loại tiền tệ. Sử dụng mã văn hóa địa phương của tôi (USA) và lấy số thập phân của tôi. ToString ("c") mang lại cho tôi $ 0.00 đầu ra, nhưng tôi muốn ký hiệu tiền tệ chính xác và số thập phân dựa trên mã.Định dạng số thập phân làm đơn vị tiền tệ dựa trên mã đơn vị tiền tệ

Có thư viện nào tồn tại không? Tất nhiên tôi có thể viết một tuyên bố chuyển đổi và các quy tắc tùy chỉnh cho từng người, nhưng nghĩ rằng điều này phải được thực hiện trước đây.

Cập nhật:

Tôi đã sửa đổi mẫu mã Jon B như sau

static IDictionary<string, string> GetCurrencyFormatStrings() 
{ 
    var result = new Dictionary<string, string>(); 

    foreach (var ci in CultureInfo.GetCultures(CultureTypes.AllCultures)) 
    { 
     try 
     { 
      var ri = new RegionInfo(ci.Name); 
      result[ri.ISOCurrencySymbol] = 
        string.Format("{0}#,#0.{1};({0}#,#0.{1})", 
           ri.CurrencySymbol, 
           new string('0', 
           i.NumberFormat.CurrencyDecimalDigits)); 
     } 
     catch { } 
    } 

    return result; 
} 

này cho phép tôi chỉ đơn giản là đi Amount.ToString (tệ [ "JPY"]), và định dạng sẽ ra dấu phân cách bằng dấu phẩy trong ngữ cảnh cục bộ của tôi, nhưng đặt ký tự tiền tệ chính xác và vị trí thập phân một cách tự động.

Hãy cho tôi biết nếu có ai có cách làm sạch hơn, hoặc tôi sẽ đánh dấu câu trả lời của Jon là chính xác trong thời gian ngắn.

+0

@AakashM - Trên thực tế nó vẫn tồn tại. Nó được gọi là 'CultureInfo'. –

+0

Rút lại các nhận xét trước đó của tôi, tôi lưu ý rằng ['RegionInfo' biết mã tiền tệ cho đơn vị tiền tệ của một khu vực] (http://msdn.microsoft.com/en-us/library/system.globalization.regioninfo.isocurrencysymbol.aspx), do đó, Framework có một số kiến ​​thức về chúng. Tôi nghi ngờ bạn sẽ phải lặp lại mặc dù, vì tôi không thấy bất kỳ tra cứu dựa trên mã tiền tệ nào. – AakashM

+0

@Ramhound 'CultureInfo' cho bạn biết cách định dạng số lượng tiền tệ trong một văn hóa nhất định. Nó không cho bạn biết rằng biểu tượng cho JPY là ¥. – AakashM

Trả lời

2

Bạn có thể xây dựng một từ điển để đi từ ký hiệu tiền tệ ISO (USD) để ký hiệu tiền tệ ($):

static void Main(string[] args) 
{ 
    var symbols = GetCurrencySymbols(); 

    Console.WriteLine("{0}{1:0.00}", symbols["USD"], 1.5M); 
    Console.WriteLine("{0}{1:0.00}", symbols["JPY"], 1.5M); 

    Console.ReadLine(); 
} 

static IDictionary<string, string> GetCurrencySymbols() 
{ 
    var result = new Dictionary<string, string>(); 

    foreach (var ci in CultureInfo.GetCultures(CultureTypes.AllCultures)) 
    { 
     try 
     { 
      var ri = new RegionInfo(ci.Name); 
      result[ri.ISOCurrencySymbol] = ri.CurrencySymbol;      
     } 
     catch { } 
    } 

    return result; 
} 

Đó là cơ bản ý tưởng, bạn sẽ cần phải tinh chỉnh cho phù hợp với nhu cầu của bạn. Lưu ý rằng bạn chắc chắn có thể sử dụng lớp CultureInfo để chuyển đổi thành chuỗi cho một nền văn hóa cụ thể, nhưng như đã lưu ý trong nhận xét của Alexei, điều này sẽ khiến cho mỗi chuỗi có một chút khác biệt (như 1,00 so với 1,00). Cho dù bạn sử dụng tùy thuộc vào nhu cầu của bạn.

+0

Điều này có vẻ khá gần - Không phải tất cả các đơn vị tiền tệ đều có 2 chữ số thập phân (mức tăng nhỏ nhất trong yên là 1), đây có phải là thông tin trong vùng không? – Superman

+1

Dường như tham chiếu đến ci.NumberFormat.CurrencyDecimalDigits đưa tôi mọi thứ tôi cần - cảm ơn! – Superman

+0

@Superman tốt để biết! –

5

nên được thực hiện bằng cách truyền CultureInfo:

CultureInfo ci = new CultureInfo("en-GB"); 
amount.ToString("C", ci); 
+4

+ 0. Tôi không nghĩ rằng nó sẽ cho kết quả @Superman trông hợp lý - phần định dạng số của đầu ra sẽ không khớp nếu 2 giá trị tiền tệ đang sử dụng dấu tách thập phân khác nhau (ví dụ: USD và EUR sẽ là $ 1.23 và "Eur" 1,23 - một trong các số sẽ trông giống như 123 cho người đọc tùy thuộc vào ngôn ngữ của người đọc). –

16
public static class DecimalExtension 
{ 
    private static readonly Dictionary<string, CultureInfo> ISOCurrenciesToACultureMap = 
     CultureInfo.GetCultures(CultureTypes.SpecificCultures) 
      .Select(c => new {c, new RegionInfo(c.LCID).ISOCurrencySymbol}) 
      .GroupBy(x => x.ISOCurrencySymbol) 
      .ToDictionary(g => g.Key, g => g.First().c, StringComparer.OrdinalIgnoreCase); 

    public static string FormatCurrency(this decimal amount, string currencyCode) 
    { 
     CultureInfo culture; 
     if (ISOCurrenciesToACultureMap.TryGetValue(currencyCode, out culture)) 
      return string.Format(culture, "{0:C}", amount); 
     return amount.ToString("0.00"); 
    } 
} 

Đây là kết quả của việc gọi FormatCurrency cho một vài mã tiền tệ khác nhau:

decimal amount = 100; 

amount.FormatCurrency("AUD"); //$100.00 
amount.FormatCurrency("GBP"); //£100.00 
amount.FormatCurrency("EUR"); //100,00 € 
amount.FormatCurrency("VND"); //100,00 ? 
amount.FormatCurrency("IRN"); //? 100.00 
+0

Triển khai tốt. –

+0

Cảm ơn @weston vì đã cải thiện mã của tôi :) – jignesh

+2

Đoạn trích tuyệt vời, nhưng tốt hơn nên sử dụng 'c.Name' thay vì' c.LCID' vì bạn có thể nhận được [CultureNotFoundExceptions] cụ thể của máy (https://msdn.microsoft). com/en-us/library/system.globalization.culturenotfoundexception (v = vs.110) .aspx) –