Java JSONParser区分对象的类型

时间:2017-09-06 08:25:55

标签: java json date serialization deserialization

我有一个Date序列化程序,在反序列化Date个对象时会添加时区,但我注意到某些Date个对象转换为String而不是长值我的String值为Date

所以,当我尝试:

Long dateValue = jsonParser.getLongValue();
Date date = new Date(dateValue);

它抛出格式异常,所以当我得到Date 形状的**String**时,我需要做

String dateString = jsonParser.getText();

dateString的值为"2017-09-06"

有没有办法知道哪种类型是 jsonParser 对象?因为instanceof在这种情况下不起作用。

2 个答案:

答案 0 :(得分:0)

如果instanceof不起作用,你可以使用将String转换为Long,这可能有效。

Long.valueOf(String s).longValue();

答案 1 :(得分:0)

如果String的值为2017-09-06,那就是为什么您无法将其作为long获取。要从Date获得String,您需要使用SimpleDateFormat

String dateString = "2017-09-06";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = sdf.parse(dateString);

唯一的问题是Date不完全是一个日期(具有定义的日/月/年)。它有no format and no timezone information,它只有自1970-01-01T00:00Z(1月1日 st 1970年午夜 UTC )以来的毫秒数 - 也称为" unix timestamp"," millis value"和many other names

使用上面的SimpleDateFormat将创建一个具有指定日期的Date(2017年9月6日 th )。由于时间未指定,因此默认为午夜,并且还将使用JVM默认时区。因此,这可以返回不同的日期(不同的millis值),具体取决于JVM中设置的时区。

如果您想使用特定的时区,只需在格式化程序中设置:

sdf.setTimeZone(TimeZone.getTimeZone("Europe/London"));

我使用了Europe/London,但你可以使用你想要的任何其他时区。您可以致电TimeZone.getAvailableIDs()获取所有可用区域的列表(并根据您的情况选择最佳区域)。

API使用IANA timezones names(始终采用Region/City格式,如America/Sao_PauloEurope/Berlin。 避免使用3个字母的缩写(例如CSTPST),因为它们是ambiguous and not standard

Java新日期/时间API

旧类(DateCalendarSimpleDateFormat)有lots of problemsdesign issues,并且它们被新API取代

如果您使用 Java 8 ,请考虑使用new java.time API。它更容易,less bugged and less error-prone than the old APIs

如果您正在使用 Java< = 7 ,则可以使用ThreeTen Backport,这是Java 8新日期/时间类的绝佳后端。对于 Android ,您还需要ThreeTenABP(更多关于如何使用它here)。

以下代码适用于两者。 唯一的区别是包名称(在Java 8中为java.time而在ThreeTen Backport(或Android的ThreeTenABP中)为org.threeten.bp),但类和方法名称是一样的。

要解析此String,您可以使用LocalDate

// get a LocalDate from 2017-09-06
LocalDate dt = LocalDate.parse(dateString);

然后您可以将其转换为Date。在下面的代码中,我模拟了SimpleDateFormat的作用:将时间设置为JVM默认时区的午夜。在Java 8中,您可以使用Date.from方法,而在Java 7中,ThreeTen Backport API具有org.threeten.bp.DateTimeUtils类:

// convert to java.util.Date (Java 8)
Date d = Date.from(dt.atStartOfDay(ZoneId.systemDefault()).toInstant());
// convert to java.util.Date (Java 7 ThreeTen Backport)
Date d = DateTimeUtils.toDate(dt.atStartOfDay(ZoneId.systemDefault()).toInstant());

只需提醒您使用默认时区可能会非常棘手,因为can be changed without notice, even at runtime,所以最好始终明确指出您正在使用的时区。

您可以使用ZoneId.of("Europe/London")指定所需的时区 - 将Europe/London更改为您想要的时区。要获取所有区域的列表,请使用ZoneId.getAvailableZoneIds()

不在问题的范围内,但您也可以使用API​​(例如Jackson)来处理JSON - 它具有来自大多数类型的内置转换,包括日期。在标记中,您会发现许多与日期操作相关的问题。