在我的应用中,我从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
类构造函数,它仅接受int值或将新的BarEntry浮动(int或float值,float)。我需要它来显示图表。
我的活动
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());
}
String dateString = "2019-11-27";
LocalDate date = LocalDate.parse(dateString);
int epochDay = (int) date.toEpochDay();
System.out.println(epochDay);
此代码段输出:
18227
文档说明:
Epoch Day计数是第0天的简单递增计数是1970-01-01(ISO)。
所以我的建议是,此数字很适合输入到您的BarEntry
构造函数中。
toEpochDay()
返回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获得)。
我已将此值18227转换为正常日期,并给出了日期1970/01/01和JSON中的2019-11-27为什么?和我应该如何纠正?
让我猜想,您有效地做到了new Date(18227)
。我的建议是,您完全避免使用Date
类,而应使用现代Java日期和时间API java.time。您为何获得1970的原因是:自纪元以来18227是days的计数,而Date
则是纪元[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。
- 在非Android Java 6和7中,获得了ThreeTen Backport,这是现代类的backport(JSR 310的ThreeTen;请参见底部的链接。
- 在(较旧的)Android上,请使用Android版的ThreeTen Backport。叫做ThreeTenABP。并确保使用子包从
org.threeten.bp
导入日期和时间类。链接 LocalDate.toEpochDay()
解释如何使用java.time。[Oracle tutorial: Date Time,首先描述Java Specification Request (JSR) 310。 [ java.time
,ThreeTen Backport project的向后移植到Java 6和7(JSR-310的ThreeTen)。[ java.time
,ThreeTen Backport的Android版本ThreeTenABP,有非常详尽的解释。