001package jmri.util;
002
003import java.text.NumberFormat;
004import java.text.ParseException;
005
006import javax.annotation.Nonnull;
007
008/**
009 * Common utility methods for Internationalization (I18N) and Localization
010 * (L12N) in the default {@link java.util.Locale}.
011 *
012 * See http://jmri.org/help/en/html/doc/Technical/I8N.shtml
013 *
014 * @author Bob Jacobsen Copyright 2014
015 * @author Steve Young Copyright 2025
016 * @since 3.9.3
017 */
018public class IntlUtilities {
019
020    // class only supplies static methods
021    private IntlUtilities(){}
022
023    /**
024     * Parse a number.
025     *
026     * Use as a locale-aware replacement for Float.valueOf("1").floatValue() and
027     * Float.parseFloat("1").floatValue().
028     * <p>
029     * White space, potentially included as a thousand separator is removed.
030     * @param val the value to parse
031     * @return a parsed number
032     * @throws java.text.ParseException if val cannot be parsed as a number
033     */
034    public static float floatValue(@Nonnull String val) throws ParseException {
035        return NumberFormat.getInstance().parse(trimWhiteSpace(val)).floatValue();
036    }
037
038    /**
039     * Parse a number.
040     *
041     * Use as a locale-aware replacement for Double.valueOf("1").doubleValue()
042     * and Double.parseDouble("1").doubleValue().
043     * <p>
044     * White space, potentially included as a thousand separator is removed.
045     * @param val the value to parse
046     * @return a parsed number
047     * @throws java.text.ParseException if val cannot be parsed as a number
048     */
049    public static double doubleValue(@Nonnull String val) throws ParseException {
050        return NumberFormat.getInstance().parse(trimWhiteSpace(val)).doubleValue();
051    }
052
053    /**
054     * Parse a number.
055     *
056     * Use as a locale-aware replacement for Integer.valueOf("1").intValue()
057     * and Integer.parseInt("1").intValue().
058     * <p>
059     * White space, potentially included as a thousand separator is removed.
060     * @param val the value to parse
061     * @return a parsed number
062     * @throws java.text.ParseException if val cannot be parsed as a number
063     */
064    public static int intValue(@Nonnull String val) throws ParseException {
065        return NumberFormat.getInstance().parse(trimWhiteSpace(val)).intValue();
066    }
067
068    private static String trimWhiteSpace(String val) {
069        return val.trim().replaceAll("\\s", "");
070    }
071
072    /**
073     * Get the text representation of a number.
074     *
075     * Use as a locale-aware replacement for String.valueOf(2.3).
076     *
077     * @param val the number
078     * @return the text representation
079     */
080    public static String valueOf(double val) {
081        return NumberFormat.getInstance().format(val);
082    }
083
084    /**
085     * Get the text representation of a number.
086     *
087     * Use as a locale-aware replacement for String.valueOf(5).
088     *
089     * @param val the number
090     * @return the text representation
091     */
092    public static String valueOf(int val) {
093        return NumberFormat.getInstance().format(val);
094    }
095
096    //private final static Logger log = LoggerFactory.getLogger(IntlUtilities.class);
097}