简体   繁体   English

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

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

In my app I am getting date from an API server as String value and I want to parse it to int but I get this error:在我的应用程序中,我从 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)

I am trying to parse into an int .我正在尝试解析为int I want to pass it to BarEntry class constructor and it takes only int value or float new BarEntry(int or float values,float).我想将它传递给BarEntry类构造函数,它只需要 int 值或 float new BarEntry(int or float values,float)。 I need it for showing Chart.我需要它来显示图表。

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 and ThreeTenABP LocalDate 和 ThreeTenABP

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

    System.out.println(epochDay);

This snippet outputs:此代码段输出:

18227 18227

The documentation explains:该文件解释说:

The Epoch Day count is a simple incrementing count of days where day 0 is 1970-01-01 (ISO). Epoch Day 计数是一个简单的递增天数,其中第 0 天是 1970-01-01 (ISO)。

So my suggestion is that this number is fine for feeding into your BarEntry constructor.所以我的建议是这个数字可以很好地输入到你的BarEntry构造函数中。

toEpochDay() returns a long . toEpochDay()返回一个long If your constructor doesn't accept a long , convert to int .如果您的构造函数不接受long ,请转换为int In the code above I did a simple cast.在上面的代码中,我做了一个简单的转换。 The risk is that we will get a very wrong result in case of int overflow for dates in the far future or the far past.风险在于,如果在遥远的未来或遥远的过去的日期发生int溢出,我们将得到非常错误的结果。 I prefer to do a range check to avoid that:我更喜欢进行范围检查以避免这种情况:

    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;

The result is the same as before.结果和以前一样。 This check is the same check that the Math.toIntExact method I mentioned in a comment does (available from Android API level 24).此检查与我在评论中提到的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?我已将此值18227转换为正常日期,它给出了今年的日期 1970/01/01而在 JSON 中它是2019-11-27为什么? and how should i correct it?我应该如何纠正它?

Let me guess, you effectively did new Date(18227) .让我猜猜,你实际上做了new Date(18227) My suggestion is that you avoid the Date class completely and stick to java.time, the modern Java date and time API.我的建议是您完全避免Date类并坚持使用现代 Java 日期和时间 API java.time。 Why you got 1970 is: 18227 is a count of days since the epoch, and Date counts milliseconds (since 00:00 UTC on the epoch day).你得到 1970 的原因是:18227 是自纪元以来的数,而Date计算毫秒(自纪元日 00:00 UTC 起)。 So you got 00:00:18.227 UTC on that day.所以那天你得到了 00:00:18.227 UTC。 We already have a LocalDate in the above code, so just use that.我们在上面的代码中已经有一个LocalDate ,所以直接使用它。

    System.out.println(date);

2019-11-27 2019-11-27

Should you need to convert the opposite way, it's easy when you know how:如果您需要以相反的方式进行转换,只要您知道如何进行,就很容易:

    LocalDate convertedBack = LocalDate.ofEpochDay(epochDay);

The result is a LocalDate with the same value.结果是具有相同值的LocalDate

Question: Doesn't java.time require Android API level 26?问题:java.time 不需要 Android API 级别 26 吗?

java.time works nicely on both older and newer Android devices. java.time 在旧的和新的 Android 设备上都能很好地工作。 It just requires at least Java 6 .它只需要至少Java 6

  • In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.在 Java 8 及更高版本以及较新的 Android 设备(从 API 级别 26 开始)中,现代 API 是内置的。
  • In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).在非 Android Java 6 和 7 中获取 ThreeTen Backport,现代类的 backport(ThreeTen 用于 JSR 310;请参阅底部的链接)。
  • On (older) Android use the Android edition of ThreeTen Backport.在(较旧的)Android 上使用 ThreeTen Backport 的 Android 版本。 It's called ThreeTenABP.它叫做 ThreeTenABP。 And make sure you import the date and time classes from org.threeten.bp with subpackages.并确保使用子包从org.threeten.bp导入日期和时间类。

Links链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM