blackdrag commented on code in PR #2688:
URL: https://github.com/apache/groovy/pull/2688#discussion_r3563222600
##########
src/main/java/org/codehaus/groovy/runtime/DefaultGroovyMethods.java:
##########
@@ -16503,6 +16505,66 @@ public static BigInteger toBigInteger(Number self) {
return NumberMath.toBigInteger(self);
}
+
//--------------------------------------------------------------------------
+ // toCurrencyString
+
+ /**
+ * Formats a Number as a currency String using the default locale.
+ *
+ * @param self a Number
+ * @return the currency-formatted String
+ * @since 6.0.0
+ */
+ public static String toCurrencyString(Number self) {
+ return NumberFormat.getCurrencyInstance().format(self);
+ }
+
+ /**
+ * Formats a Number as a currency String using the given locale.
+ * <pre class="groovyTestCase">
+ * assert 1234.5.toCurrencyString(Locale.US) == '$1,234.50'
+ * </pre>
+ *
+ * @param self a Number
+ * @param locale the locale defining the currency format
+ * @return the currency-formatted String
+ * @since 6.0.0
+ */
+ public static String toCurrencyString(Number self, Locale locale) {
+ return NumberFormat.getCurrencyInstance(locale).format(self);
+ }
+
+
//--------------------------------------------------------------------------
+ // toPercentString
+
+ /**
+ * Formats a Number as a percent String using the default locale.
+ * The value is scaled by 100 (e.g. {@code 0.945} becomes {@code 94.5%}).
+ *
+ * @param self a Number
+ * @return the percent-formatted String
+ * @since 6.0.0
+ */
+ public static String toPercentString(Number self) {
+ return NumberFormat.getPercentInstance().format(self);
+ }
+
+ /**
+ * Formats a Number as a percent String using the given locale.
+ * The value is scaled by 100 (e.g. {@code 0.945} becomes {@code 94.5%}).
+ * <pre class="groovyTestCase">
+ * assert 0.5.toPercentString(Locale.US) == '50%'
+ * </pre>
+ *
+ * @param self a Number
+ * @param locale the locale defining the percent format
+ * @return the percent-formatted String
+ * @since 6.0.0
+ */
+ public static String toPercentString(Number self, Locale locale) {
+ return NumberFormat.getPercentInstance(locale).format(self);
+ }
+
Review Comment:
I usually work with multilingual Apps, already supporting Germany and
Switzerland influences number formatting and of course currency symbols - the
language is not even different for this case. The effect is that I have to
avoid everything that uses some kind of default Locale. And don't get me
started on date and time. Thus for my practical work these methods are useless.
I would rather prefer a fixed format, that is not depending on the default
locale - for everything that depends on the locale in DGM. Which would make the
percent version ok, but I would still not offer the currency variant.
##########
src/test/groovy/org/codehaus/groovy/runtime/StringGroovyMethodsTest.java:
##########
@@ -261,4 +263,38 @@ public void testToMethods() {
assertEquals(Boolean.FALSE, StringGroovyMethods.toBoolean("n"));
assertEquals(Boolean.FALSE, StringGroovyMethods.toBoolean("0"));
}
+
+ @Test
+ public void testToNumberWithLocale() {
+ assertEquals(1234.5, StringGroovyMethods.toNumber("1,234.5",
Locale.US).doubleValue(), 0.0);
+ assertEquals(1234.5, StringGroovyMethods.toNumber("1.234,5",
Locale.GERMANY).doubleValue(), 0.0);
+ assertEquals(42.0, StringGroovyMethods.toNumber(" 42 ",
Locale.US).doubleValue(), 0.0); // surrounding whitespace trimmed
+ assertThrows(NumberFormatException.class, () ->
StringGroovyMethods.toNumber("abc", Locale.US));
+ // strict: the whole input must parse, trailing junk is rejected (not
silently truncated)
+ assertThrows(NumberFormatException.class, () ->
StringGroovyMethods.toNumber("12abc", Locale.US));
+ assertThrows(NumberFormatException.class, () ->
StringGroovyMethods.toNumber("", Locale.US));
+ }
+
+ @Test
+ public void testToCurrencyNumberWithLocale() {
+ Number us = StringGroovyMethods.toCurrencyNumber("$1,234.50",
Locale.US);
+ assertEquals(new BigDecimal("1234.50"), us);
+ assertTrue(us instanceof BigDecimal, "currency should parse to an
exact BigDecimal");
+ // round-trip through the formatter to avoid hard-coding
locale-specific symbols/spacing
+ String formatted = DefaultGroovyMethods.toCurrencyString(new
BigDecimal("1234.50"), Locale.GERMANY);
+ assertEquals(new BigDecimal("1234.50"),
StringGroovyMethods.toCurrencyNumber(formatted, Locale.GERMANY));
+ assertThrows(NumberFormatException.class, () ->
StringGroovyMethods.toCurrencyNumber("nope", Locale.US));
+ // strict: trailing text after the amount is rejected
+ assertThrows(NumberFormatException.class, () ->
StringGroovyMethods.toCurrencyNumber("$1,234.50 and more", Locale.US));
+ }
+
+ @Test
+ public void testToPercentNumberWithLocale() {
+ assertEquals(0.5, StringGroovyMethods.toPercentNumber("50%",
Locale.US).doubleValue(), 0.0);
+ // Turkish places the percent sign before the number
+ assertEquals(0.5, StringGroovyMethods.toPercentNumber("%50", new
Locale("tr", "TR")).doubleValue(), 0.0);
+ assertThrows(NumberFormatException.class, () ->
StringGroovyMethods.toPercentNumber("x", Locale.US));
+ // strict: trailing text after the percent is rejected
+ assertThrows(NumberFormatException.class, () ->
StringGroovyMethods.toPercentNumber("50% off", Locale.US));
+ }
Review Comment:
don't forget testing with default local. (saving Locale.getDefault, setting
with Locale.setDefault before test and restoring with Locale.setDefault after
the test).
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]