-3

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:

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. I want to pass it to BarEntry class constructor and it takes only int value or 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());
}
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Mohammed Qadah
  • 75
  • 1
  • 10
  • 5
    Well evidently your string is `"2019-11-27"`, which is not parsable to an int. What would you like to do with it? – khelwood Dec 13 '19 at 19:31
  • @khelwood because i want to pass it to BarEntry class constructor and it takes only int value or float new BarEntry(int or float values,float); i need it for showing Chart – Mohammed Qadah Dec 13 '19 at 19:36
  • I suggest `Math.toIntExact(LocalDate.parse("2019-11-27").toEpochDay())`. The example yields 18227, an `int` that you can comfortably pass to the `BarEntry` constructor. – Ole V.V. Dec 13 '19 at 19:39
  • @OleV.V. your suggestion requires API level 24 and mine is 19.Is there other way? – Mohammed Qadah Dec 13 '19 at 19:49
  • `LocalDate` is part of java.time, the modern Java date and time API, which is built-in from API level 26. However, it has also been backported. So you can use it on API level 19 if you add [ThreeTenABP](https://github.com/JakeWharton/ThreeTenABP) to your Android project and make sure you import `org.threeten.bp.LocalDate`. See [How to use ThreeTenABP in Android Project](https://stackoverflow.com/questions/38922754/how-to-use-threetenabp-in-android-project) for a very thorough explanation. – Ole V.V. Dec 13 '19 at 19:55
  • @OleV.V. It's good idea but 2nd problem is `Math.toIntExact()` requires API 24 – Mohammed Qadah Dec 13 '19 at 20:02
  • 1
    Uh oh, I wasn’t aware of that one, sorry. You may simply cast: `(int) LocalDate.parse("2019-11-27").toEpochDay()`. And/or code a range check yourself before casting. You may also cast to `float` instead, then you need no range check. – Ole V.V. Dec 13 '19 at 20:08
  • @OleV.V. Thank you finally i got the date in `int` value but the yields is **18227**. Is it possible to convert it to normal date? – Mohammed Qadah Dec 13 '19 at 20:22
  • @OleV.V. 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? – Mohammed Qadah Dec 13 '19 at 20:49
  • 1
    You're getting the epoch day, you wouldn't pass days to the constructor for date, as it takes milliseconds if my memory serves – Rogue Dec 14 '19 at 04:46

1 Answers1

2

LocalDate and ThreeTenABP

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

    System.out.println(epochDay);

This snippet outputs:

18227

The documentation explains:

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

So my suggestion is that this number is fine for feeding into your BarEntry constructor.

toEpochDay() returns a long. If your constructor doesn’t accept a long, convert to 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. 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).

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?

Let me guess, you effectively did 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. 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). So you got 00:00:18.227 UTC on that day. We already have a LocalDate in the above code, so just use that.

    System.out.println(date);

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.

Question: Doesn’t java.time require Android API level 26?

java.time works nicely on both older and newer Android devices. It just requires at least Java 6.

  • In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
  • 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).
  • On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.

Links

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • Ok thank you for your help,I accepted your answer,and i have another question in my account,could you please help me with that? i will paste the link here: [https://stackoverflow.com/questions/59306683/is-it-possible-to-show-a-chart-by-using-mpandroid-from-web-server-api] – Mohammed Qadah Dec 14 '19 at 14:45
  • Thank you, @MohammedQadah. I’m afraid I won’t be able to help with that other one. In any case I will take a closer look when I find the time. – Ole V.V. Dec 14 '19 at 14:56
  • Ok Thank you so much,i will wait – Mohammed Qadah Dec 14 '19 at 14:58