我有一个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
在这种情况下不起作用。
答案 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_Paulo
或Europe/Berlin
。
避免使用3个字母的缩写(例如CST
或PST
),因为它们是ambiguous and not standard。
旧类(Date
,Calendar
和SimpleDateFormat
)有lots of problems和design 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 - 它具有来自大多数类型的内置转换,包括日期。在jackson标记中,您会发现许多与日期操作相关的问题。