java.lang.NumberFormatException:对于输入字符串:“2019-11-27”

java.lang.NumberFormatException: For input string: “2019-11-27”

在我的应用程序中,我从 API 服务器获取日期作为 String 值,我想将其解析为 int 但我收到此错误:

Caused by: java.lang.NumberFormatException: For input string: "2019-11-27"
at java.lang.Integer.parseInt(Integer.java: 521)
at java.lang.Integer.parseInt(Integer.java: 556)

我正在尝试解析为 int。我想将它传递给 BarEntry class 构造函数,它只需要 int value 或 float new BarEntry(int or float values,float)。我需要它来显示图表。

My Activity

try {
    Response response = client.newCall(request).execute();
    Log.d("Response", response.toString());
    JSONObject object = new JSONObject(Objects.requireNonNull(response.body()).string());
    JSONObject rates = object.getJSONObject("rates");
    Iterator < String > iterator = rates.keys();
    while (iterator.hasNext()) {
        String keyDate = iterator.next(); // this date which i want to parse to int value
        String cad = rates.getJSONObject(keyDate).getString("CAD");
        @SuppressLint("DefaultLocale") String value = String.format("%.4s", cad);
        float value1 = Float.parseFloat(value);
        int date = Integer.parseInt(keyDate);
        Log.d("TAG", date + "");
        //Log.d("TAG", value1 + "");

        //barEntries.add(new BarEntry(keyDate, value1));

    }
} catch (IOException | JSONException e) {
    e.printStackTrace();
    Log.d("ChartActivity", e.toString());
}

LocalDate 和 ThreeTenABP

    String dateString = "2019-11-27";
    LocalDate date = LocalDate.parse(dateString);
    int epochDay = (int) date.toEpochDay();

    System.out.println(epochDay);

此代码段输出:

18227

文档解释:

The Epoch Day count is a simple incrementing count of days where day 0 is 1970-01-01 (ISO).

所以我的建议是,这个数字适合输入您的 BarEntry 构造函数。

toEpochDay()returns一个long。如果您的构造函数不接受 long,请转换为 int。在上面的代码中,我做了一个简单的转换。风险在于,如果 int 溢出的日期在遥远的未来或遥远的过去,我们将得到一个非常错误的结果。我更喜欢做一个范围检查来避免这种情况:

    long epochDayLong = date.toEpochDay();
    if (epochDayLong < Integer.MIN_VALUE || epochDayLong > Integer.MAX_VALUE) {
        throw new IllegalStateException("Date " + date + " is out of range");
    }
    int epochDay = (int) epochDayLong;

结果和之前一样。此检查与我在评论中提到的 Math.toIntExact 方法所做的检查相同(可从 Android API 级别 24 获得)。

I had converted this value 18227 to normal date and it gives date of this year 1970/01/01 and in JSON it's 2019-11-27 why? and how should i correct it?

让我猜猜,您实际上做到了 new Date(18227)。我的建议是你完全避免 Date class 并坚持使用 java.time,现代 Java 日期和时间 API。为什么你得到 1970 是:18227 是自纪元以来 的计数,而 Date 计数 毫秒 (因为 00:00 纪元日的 UTC)。所以那天你得到了 00:00:18.227 UTC。我们在上面的代码中已经有一个LocalDate,所以直接使用它。

    System.out.println(date);

2019-11-27

如果你需要转换成相反的方式,知道怎么做就很容易:

    LocalDate convertedBack = LocalDate.ofEpochDay(epochDay);

结果是具有相同值的 LocalDate

问题:java.time 不需要 Android API 26 级吗?

java.time 在新旧 Android 设备上都能很好地工作。它只需要至少 Java 6.

  • 在 Java 8 和更新的 Android 设备上(从 API 级别 26)内置现代 API。
  • In-Android Java 6 和 7 获得 ThreeTen Backport,现代 classes 的 backport(ThreeTen 用于 JSR 310;请参阅底部的链接) .
  • 在(较旧的)Android 使用 ThreeTen Backport 的 Android 版本。它叫做 ThreeTenABP。并确保使用子包从 org.threeten.bp 导入日期和时间 classes。

链接