SOAP Web服务解析日期从字符串返回D-1值



我正在使用 org.apache.cxf.xjc.runtime.DataTypeAdapter.parseDate(StringDate)将输入字符串日期从XML到Java日期分析。但是我得到了一个带有第1天价值的日期对象。

例如

<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();
}

java.Time

    String birth = "1939-11-19+01:00";
    LocalDate date = LocalDate.parse(birth, DateTimeFormatter.ISO_OFFSET_DATE);
    System.out.println(date);

此打印

1939-11-19

a java.time.LocalDate是没有日期的日期,因此与您的要求完全匹配。同时,java.util.Date和朋友长期以来已经过时,并且被证明设计不佳。java.time,现代的Java日期和时间API,可以使用得更好。所以我的第一个建议是您在这里停下来。

如果您确实需要Date,例如,对于旧的API,请首先意识到,尽管名称并不代表日期。它代表了一个时间点,在那个时间点,日期到处都不会相同。正如您所知,这可能会导致您的问题:parseDateparseDateTime在相关日期在UTC的指定偏移量时将字符串解析为00:00。在此时间点,日期可能在您的时区不相同,因此,当您打印您获得的Date时,请调用其toString方法,您可能会得到不同的日期。我了解您希望您在自己的时区0:00的时间(CET,可能是中欧时代,反过来又是一个不同时区的名称,该区域可能是1939年在Offsets 0或 01处的数字区域;您观察到的结果在欧洲/巴黎,非洲/欧洲/欧洲/安道,欧洲/马德里和欧洲/摩纳哥的时区是有意义的,所有这些都处于抵销0(。转换:

    Date oldfashionedDateObject 
            = Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant());
    System.out.println(oldfashionedDateObject);

此印刷

Sun Nov 19 00:00:00 CET 1939

我的时区设置为美国/new_york和欧洲/莫斯科进行了测试,并且始终获得Sun Nov 19 00:00:00,仅在不同的时区,ESTMSK

Java 6和Threeten Backport

我知道您必须使用Java 6. java.time在Threeten Backport中已将其退回到Java 6和7。因此,从底部的链接中获取此信息并将其添加到您的项目中,上面的代码将起作用,除了转换的发生略有不同:

    Date oldfashionedDateObject
            = DateTimeUtils.toDate(date.atStartOfDay(ZoneId.systemDefault()).toInstant());

您无需重写所有代码即可使用Threeten Backport,尤其是如果您在某些部分不信任现代API可以按照自己想要的方式行事。以上片段可以与您已经拥有的代码共存。

真正的老式方式

如果您真的坚持,我可以找到使用DatatypeConverterCalendarDate的方式:

    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的时区进行了测试。

链接

  • Oracle教程:说明如何使用java.time的日期时间。
  • Java规范请求(JSR(310,首先描述了java.time
  • Threeten Backport Project,java.time的Backport到Java 6和7(JSR-310的Threeten(。
  • Threetenabp,Threeten Backport的Android Edition
  • 问题:如何在Android项目中使用Threetenabp,并具有非常详尽的解释。

相关内容

  • 没有找到相关文章

最新更新