Search code examples
androidnumberformatexception

Long.parseLong("+2013") throws NumberFormatException


I'm trying to get an external Java library to work with Android but its throwing errors while working with dates.

I've narrowed it down to this line:

Long year = Long.parseLong("+2013");

which throws a

Caused by: java.lang.NumberFormatException: Invalid long: "+2013"

However, the code is valid and working in a pure Java application. Why does Long.parseLong() works differently in an Android app?

Android's documentation states that '+' Ascii signs are recognized:

public static long parseLong (String string)

Parses the specified string as a signed decimal long value. The ASCII characters - ('-') and + ('+') are recognized as the minus and plus signs.


Solution

  • Thanks everyone! Managed to find out the problem.

    It seems that API 17: Android 4.2 (Jelly Bean) is causing issues. The API doesn't handle the '+' sign in the parseLong() correctly.

    Solved it changing the compile SDK to API 21 and later.

    API 20 parseLong()

        /**
     * Parses the specified string as a signed long value using the specified
     * radix. The ASCII character \u002d ('-') is recognized as the minus sign.
     *
     * @param string
     *            the string representation of a long value.
     * @param radix
     *            the radix to use when parsing.
     * @return the primitive long value represented by {@code string} using
     *         {@code radix}.
     * @throws NumberFormatException
     *             if {@code string} cannot be parsed as a long value, or
     *             {@code radix < Character.MIN_RADIX ||
     *             radix > Character.MAX_RADIX}.
     */
    public static long parseLong(String string, int radix) throws NumberFormatException {
        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
            throw new NumberFormatException("Invalid radix: " + radix);
        }
        if (string == null) {
            throw invalidLong(string);
        }
        int length = string.length(), i = 0;
        if (length == 0) {
            throw invalidLong(string);
        }
        boolean negative = string.charAt(i) == '-';
        if (negative && ++i == length) {
            throw invalidLong(string);
        }
    
        return parse(string, i, radix, negative);
    }
    

    API 21 parseLong()

        /**
     * Parses the specified string as a signed long value using the specified
     * radix. The ASCII characters \u002d ('-') and \u002b ('+') are recognized
     * as the minus and plus signs.
     *
     * @param string
     *            the string representation of a long value.
     * @param radix
     *            the radix to use when parsing.
     * @return the primitive long value represented by {@code string} using
     *         {@code radix}.
     * @throws NumberFormatException
     *             if {@code string} cannot be parsed as a long value, or
     *             {@code radix < Character.MIN_RADIX ||
     *             radix > Character.MAX_RADIX}.
     */
    public static long parseLong(String string, int radix) throws NumberFormatException {
        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
            throw new NumberFormatException("Invalid radix: " + radix);
        }
        if (string == null || string.isEmpty()) {
            throw invalidLong(string);
        }
        char firstChar = string.charAt(0);
        int firstDigitIndex = (firstChar == '-' || firstChar == '+') ? 1 : 0;
        if (firstDigitIndex == string.length()) {
            throw invalidLong(string);
        }
    
        return parse(string, firstDigitIndex, radix, firstChar == '-');
    }