我正在使用org.apache.cxf.xjc.runtime.DataTypeAdapter.parseDate(StringDate)
来解析从XML到JAVA日期的输入字符串日期。但是我得到了具有第1天值的Date对象。
例如
<birth>1939-11-19+01:00</birth>
我想忽略偏移量。我只想要日期,所以不管偏移是什么,我都应该
Sun Nov 19 00:00:00 CET 1939
但我确实得到了:
Sat Nov 18 23:00:00 CET 1939
问题出在日期时间偏移的水平上。我试图通过忽略时间偏移来修复它,但这不起作用。我正在使用java 6(约束项目)。有什么想法吗?
我最好尝试一个最小,完整和可验证的例子:
public static Date parse(final String str) {
Calendar c = DatatypeConverter.parseDateTime(str);
System.out.println(str + "\t" + c.getTime().getTime() / 1000);
return c.getTime();
}
答案 0 :(得分:1)
String birth = "1939-11-19+01:00";
LocalDate date = LocalDate.parse(birth, DateTimeFormatter.ISO_OFFSET_DATE);
System.out.println(date);
打印
1939-11-19
java.time.LocalDate
是没有时间的日期,因此这完全符合您的要求。与此同时java.util.Date
和朋友们已经过时了,而且设计得很差。 java.time
,现代Java日期和时间API,使用起来非常好。所以我的第一个建议是你到此为止。
如果确实需要Date
,例如遗留API,请首先意识到尽管名称不代表日期。它代表一个时间点,在那个时间点,日期在各地都不一样。正如您所知,这可能会导致您的问题:parseDate
和parseDateTime
将您的字符串解析为00:00,在指定的日期与UTC相关的偏移量。此时,您的时区中的日期可能不同,因此当您打印所获得的Date
,从而调用其toString
方法时,您可能会得到不同的日期。我知道你想要在你自己的时区0:00的时间(CET,可能是中欧时间,反过来是1939年那个日期可能在0或+01偏移的几个不同时区的名称;你所观察到的结果在时区欧洲/巴黎,非洲/休达,欧洲/安道尔,欧洲/马德里和欧洲/摩纳哥都有意义,所有这些都是0。转换:
Date oldfashionedDateObject
= Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant());
System.out.println(oldfashionedDateObject);
此印刷
Sun Nov 19 00:00:00 CET 1939
我测试了我的时区设置为America / New_York和欧洲/莫斯科,并且总是得到Sun Nov 19 00:00:00
,仅在不同的时区,EST
和MSK
。
我知道您必须使用Java 6. java.time
已被移植到ThreeTen Backport中的Java 6和7。所以从底部的链接获取并将其添加到您的项目中,上述代码将起作用,但转换的发生方式略有不同:
Date oldfashionedDateObject
= DateTimeUtils.toDate(date.atStartOfDay(ZoneId.systemDefault()).toInstant());
您无需重写所有代码即可使用ThreeTen Backport,特别是如果有些部分您不相信现代API可以按照您的方式运行。上面的代码段可以很好地与您已有的代码共存。
如果您真的坚持,我可以找到使用Date
和DatatypeConverter
获取Calendar
的方式:
Calendar calWithParsedOffset = DatatypeConverter.parseDate(birth);
Calendar calWithMyTimeZone = Calendar.getInstance(TimeZone.getDefault());
calWithMyTimeZone.clear();
calWithMyTimeZone.set(calWithParsedOffset.get(Calendar.YEAR),
calWithParsedOffset.get(Calendar.MONTH),
calWithParsedOffset.get(Calendar.DAY_OF_MONTH));
Date oldfashionedDateObject = calWithMyTimeZone.getTime();
System.out.println(oldfashionedDateObject);
我们不能只改变我们从解析中得到的Calendar
的偏移量或时区,因为这不会改变它的时间点,因此不会改变我们得到的Date
对象。相反,我们需要将不同的Calendar
对象设置为第一个Calendar
的年,月和日。对clear()
的调用将小时,分钟,秒和毫秒设置为0.此片段也已经过测试,我的JVM时区设置为America / New_York和Europe / Moscow。
java.time
。java.time
。java.time
向Java 6和7的后端(JST-310的ThreeTen)。