1

Вот пример кода, который я использую с Moneta version 1.1:

Locale LANG = Locale.CHINA; // also tried new Locale("pl", "PL"); 

    final MonetaryAmountFormat format = MonetaryFormats.getAmountFormat(
      AmountFormatQueryBuilder.of(LANG) 
        .set(CurrencyStyle.SYMBOL) 
        .set("pattern", "#,##0.00### ¤") 
        .build() 
    ); 
    final String formatted = format.format(Money.of(new BigDecimal("1234.56"), Monetary.getCurrency(LANG))); 

    System.out.println(formatted); 

    System.out.println(format.parse(formatted).getNumber()); 

Это должно работать, так как я преобразовать тот же объект назад и вперед. Если у меня что-то не так, и конвертер не является двусторонним для других валют, чем $, € или £.

Последняя строка падает с:

Exception in thread "main" java.lang.IllegalArgumentException: Invalid error index > input.length 
at javax.money.format.MonetaryParseException.<init>(MonetaryParseException.java:56) 
at org.javamoney.moneta.internal.format.AmountNumberToken.parse(AmountNumberToken.java:140) 
at org.javamoney.moneta.internal.format.DefaultMonetaryAmountFormat.parse(DefaultMonetaryAmountFormat.java:190) 
at test.main(test.java:27) 

Это происходит, если при условии, язык не связан с одним из $, € или £. Например, этот код будет работать для Locale.US, но будет аварийно завершен для Locale.CHINA, а также с new Locale("pl", "PL"). Таким образом, это не только проблема с пользовательским значением Locale, но и с теми, которые статически предопределены.

Я вырыл немного во внутреннюю упаковку и обнаружил org.javamoney.moneta.internal.format.CurrencyToken.parse(CurrencyToken.java:196), который выглядит следующим образом:

case SYMBOL: 
    if (token.startsWith("$")) { 
     cur = Monetary.getCurrency("USD"); 
     context.consume("$"); 
    } else if (token.startsWith("€")) { 
     cur = Monetary.getCurrency("EUR"); 
     context.consume("€"); 
    } else if (token.startsWith("£")) { 
     cur = Monetary.getCurrency("GBP"); 
     context.consume("£"); 
    } else { 
     cur = Monetary.getCurrency(token); 
     context.consume(token); 
    } 
    context.setParsedCurrency(cur); 
    break; 

Есть ли способ, чтобы сделать свой код выше работы, отличных от $ валют, € или £?


меня попробовать несколько вещей, например, при условии Locale.CANADA они также имеют $ как символ валюты, так что выполнить без сбоев, но возвращает неверные данные

Locale LANG = Locale.CANADA; 

    final MonetaryAmountFormat format = MonetaryFormats.getAmountFormat(
      AmountFormatQueryBuilder.of(LANG) 
        .set(CurrencyStyle.SYMBOL) 
        .set("pattern", "#,##0.00### ¤") 
        .build() 
    ); 
    final String formatted = format.format(Money.of(new BigDecimal("1234.56"), Monetary.getCurrency(LANG))); 

    System.out.println(formatted); 

    System.out.println(format.parse(formatted).getCurrency().getCurrencyCode()); 

последняя линия возврата USD вместо CAD который это то, что делает if-else для $. Я думаю, что это также ошибочно предполагает, что символ - валюта - одно к одному.

ответ

0

Мы работаем над решением вопросов, поднятых вопросов https://github.com/JavaMoney/jsr354-ri/issues/149.

Ожидайте исправления Moneta для этого и других вопросов в ближайшее время.

Werner