这是有效的日期格式吗 - 2007-12-13+01:00?
Is this a valid date format - 2007-12-13+01:00?
我们的情况很奇怪。 我们期望来自 Web 服务的一些数据 然后我们在 java 代码中处理它。突然,它开始失败了。
我们发现,我们收到的日期格式如下:2007-12-13+01:00 并抛出异常:java.lang.NumberFormatException:无效date/time。我们使用 JAXB 来编组响应并期望日期为 java.util.Date。到目前为止,我没有找到任何处理日期的代码行,没有修剪、转换或任何东西。只是编组。
现在对于这个格式是对是错,是谁造成的,存在争议。有趣的是,最近 java 代码没有任何变化,唯一的区别在于构建的计算机。
这可能是由于 java 版本、ANT 配置不同造成的?您有什么建议会导致此类问题吗?如果您有任何问题,请询问。可以的话我会尽量回答的。
我不认为它是一种有效的 ISO-8601(或 RFC 3339)格式,这是通常用于 Web 服务的格式 - 它似乎只在指定时间时包含时区偏移量.
但是,如评论中所述,它 是 有效的 XML schema 表示:
The lexical space of date consists of finite-length sequences of characters of the form: '-'? yyyy '-' mm '-' dd zzzzzz?
where the date and optional timezone are represented exactly the same way as they are for dateTime. The first moment of the interval is that represented by: '-' yyyy '-' mm '-' dd 'T00:00:00' zzzzzz?
and the least upper bound of the interval is the timeline point represented (noncanonically) by: '-' yyyy '-' mm '-' dd 'T24:00:00' zzzzzz?
.
如果您想表示特定时区的一整天,这有点有意义 - 虽然因为它只指定偏移量而不是时区 ID,它会在 23 或 25 小时的日子里用夏令时转换失败: (
我不能说我个人曾经见过它在野外使用,也没有在 date/time API 中建模。
官方ISO 8601论文说(不能link,因为它需要你购买):
The zone designator is empty if use is made of local time in
accordance with 4.2.2.2 through 4.2.2.4, it is the UTC designator [Z]
if use is made of UTC of day in accordance with 4.2.4 and it is the
difference-component if use is made of local time and the difference
from UTC in accordance with 4.2.5.2.
我以某种方式解释此声明,好像区域指示符仅在任何时间组件的上下文中才有意义。所以答案是:
➥ 您的输入字符串并不真正 ISO 8601 兼容,但是 XML-schema 兼容 您应该期待使用 JAXB 的 Web 服务。请参阅好兄弟答案中的引文, 和 Jon Skeet 的。
所以是的,您必须考虑到与 XML 兼容的 Web 服务将提供此类数据的可能性(尽管非常可疑,但更有可能的是 Web 服务只是未能提供完整的数据)由于内部错误导致的日期时间)。
如何解释日期和偏移量的组合是另一个好问题。 XML-schema 将解释解释为一个时间间隔(一整天),但此时间间隔不可映射 1:1 到一个时间点(您的 java.util.Date
结果)。也许您应该简单地假设午夜并使用偏移量将结果映射到 java.util.Date
。或者更好:您应该询问 Web 服务背后的负责人,他们为什么提供此类数据以及如何解释这些数据。
顺便说一句,我记得java.time (built into Java 8) originally planned to introduce the type OffsetDate
in analogy to OffsetDateTime
,但终于放弃了。
这是有效的日期格式吗 - 2007-12-13+01:00?
是的,格式的官方描述见下面的link:
你的错误
We found out, that we receive the date in such format:
2007-12-13+01:00 and it throws out an exception:
java.lang.NumberFormatException: Invalid date/time
java.lang.NumberFormatException: Invalid date/time
at org.apache.axis.encoding.ser.SimpleDeserializer.onEndElement(SimpleDeserializer.java:180)
at org.apache.axis.encoding.DeserializerImpl.endElement(DeserializerImpl.java:502)
at org.apache.axis.encoding.DeserializationContext.endElement(DeserializationContext.java:1087)
at org.apache.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.java:171)
at org.apache.axis.message.MessageElement.publishToHandler(MessageElement.java:1141)
at org.apache.axis.message.RPCElement.deserialize(RPCElement.java:236)
at org.apache.axis.message.RPCElement.getParams(RPCElement.java:384)
at org.apache.axis.client.Call.invoke(Call.java:2467)
at org.apache.axis.client.Call.invoke(Call.java:2366)
at org.apache.axis.client.Call.invoke(Call.java:1812)
这似乎是 Axis 而不是 JAXB 中的错误。
在 JAXB 中处理此格式
下面是在 JAXB 中使用此格式的示例。
Java 型号
在此示例中,我们将使用 Date
、Calendar
和 XMLGregorianCalendar
来处理日期:
import java.util.*;
import javax.xml.bind.annotation.*;
import javax.xml.datatype.XMLGregorianCalendar;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Foo {
private Date date;
private Calendar cal;
private XMLGregorianCalendar xgc;
}
演示代码
input.xml
下面是我们将解组的 XML 文档,请注意所有日期值与您问题中的相同。
<?xml version="1.0" encoding="UTF-8"?>
<foo>
<date>2007-12-13+01:00</date>
<cal>2007-12-13+01:00</cal>
<xgc>2007-12-13+01:00</xgc>
</foo>
演示
下面是一些演示代码,我们将在其中解组 XML 文档以填充每个日期字段,然后将对象编组回 XML。
import javax.xml.bind.*;
import java.io.File;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Foo.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("input.xml");
Foo foo = (Foo) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(foo, System.out);
}
}
输出
下面是 运行 演示代码的输出,我们看到所有值都已正确转换。请注意,Date
和 Calendar
值默认为默认的日期时间表示形式。您可以使用 @XmlSchemaType
注释来控制它。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<foo>
<date>2007-12-12T18:00:00-05:00</date>
<cal>2007-12-13T00:00:00+01:00</cal>
<xgc>2007-12-13+01:00</xgc>
</foo>
我们的情况很奇怪。 我们期望来自 Web 服务的一些数据 然后我们在 java 代码中处理它。突然,它开始失败了。
我们发现,我们收到的日期格式如下:2007-12-13+01:00 并抛出异常:java.lang.NumberFormatException:无效date/time。我们使用 JAXB 来编组响应并期望日期为 java.util.Date。到目前为止,我没有找到任何处理日期的代码行,没有修剪、转换或任何东西。只是编组。
现在对于这个格式是对是错,是谁造成的,存在争议。有趣的是,最近 java 代码没有任何变化,唯一的区别在于构建的计算机。
这可能是由于 java 版本、ANT 配置不同造成的?您有什么建议会导致此类问题吗?如果您有任何问题,请询问。可以的话我会尽量回答的。
我不认为它是一种有效的 ISO-8601(或 RFC 3339)格式,这是通常用于 Web 服务的格式 - 它似乎只在指定时间时包含时区偏移量.
但是,如评论中所述,它 是 有效的 XML schema 表示:
The lexical space of date consists of finite-length sequences of characters of the form:
'-'? yyyy '-' mm '-' dd zzzzzz?
where the date and optional timezone are represented exactly the same way as they are for dateTime. The first moment of the interval is that represented by:'-' yyyy '-' mm '-' dd 'T00:00:00' zzzzzz?
and the least upper bound of the interval is the timeline point represented (noncanonically) by:'-' yyyy '-' mm '-' dd 'T24:00:00' zzzzzz?
.
如果您想表示特定时区的一整天,这有点有意义 - 虽然因为它只指定偏移量而不是时区 ID,它会在 23 或 25 小时的日子里用夏令时转换失败: (
我不能说我个人曾经见过它在野外使用,也没有在 date/time API 中建模。
官方ISO 8601论文说(不能link,因为它需要你购买):
The zone designator is empty if use is made of local time in accordance with 4.2.2.2 through 4.2.2.4, it is the UTC designator [Z] if use is made of UTC of day in accordance with 4.2.4 and it is the difference-component if use is made of local time and the difference from UTC in accordance with 4.2.5.2.
我以某种方式解释此声明,好像区域指示符仅在任何时间组件的上下文中才有意义。所以答案是:
➥ 您的输入字符串并不真正 ISO 8601 兼容,但是 XML-schema 兼容 您应该期待使用 JAXB 的 Web 服务。请参阅好兄弟答案中的引文,
所以是的,您必须考虑到与 XML 兼容的 Web 服务将提供此类数据的可能性(尽管非常可疑,但更有可能的是 Web 服务只是未能提供完整的数据)由于内部错误导致的日期时间)。
如何解释日期和偏移量的组合是另一个好问题。 XML-schema 将解释解释为一个时间间隔(一整天),但此时间间隔不可映射 1:1 到一个时间点(您的 java.util.Date
结果)。也许您应该简单地假设午夜并使用偏移量将结果映射到 java.util.Date
。或者更好:您应该询问 Web 服务背后的负责人,他们为什么提供此类数据以及如何解释这些数据。
顺便说一句,我记得java.time (built into Java 8) originally planned to introduce the type OffsetDate
in analogy to OffsetDateTime
,但终于放弃了。
这是有效的日期格式吗 - 2007-12-13+01:00?
是的,格式的官方描述见下面的link:
你的错误
We found out, that we receive the date in such format: 2007-12-13+01:00 and it throws out an exception: java.lang.NumberFormatException: Invalid date/time
java.lang.NumberFormatException: Invalid date/time
at org.apache.axis.encoding.ser.SimpleDeserializer.onEndElement(SimpleDeserializer.java:180)
at org.apache.axis.encoding.DeserializerImpl.endElement(DeserializerImpl.java:502)
at org.apache.axis.encoding.DeserializationContext.endElement(DeserializationContext.java:1087)
at org.apache.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.java:171)
at org.apache.axis.message.MessageElement.publishToHandler(MessageElement.java:1141)
at org.apache.axis.message.RPCElement.deserialize(RPCElement.java:236)
at org.apache.axis.message.RPCElement.getParams(RPCElement.java:384)
at org.apache.axis.client.Call.invoke(Call.java:2467)
at org.apache.axis.client.Call.invoke(Call.java:2366)
at org.apache.axis.client.Call.invoke(Call.java:1812)
这似乎是 Axis 而不是 JAXB 中的错误。
在 JAXB 中处理此格式
下面是在 JAXB 中使用此格式的示例。
Java 型号
在此示例中,我们将使用 Date
、Calendar
和 XMLGregorianCalendar
来处理日期:
import java.util.*;
import javax.xml.bind.annotation.*;
import javax.xml.datatype.XMLGregorianCalendar;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Foo {
private Date date;
private Calendar cal;
private XMLGregorianCalendar xgc;
}
演示代码
input.xml
下面是我们将解组的 XML 文档,请注意所有日期值与您问题中的相同。
<?xml version="1.0" encoding="UTF-8"?>
<foo>
<date>2007-12-13+01:00</date>
<cal>2007-12-13+01:00</cal>
<xgc>2007-12-13+01:00</xgc>
</foo>
演示
下面是一些演示代码,我们将在其中解组 XML 文档以填充每个日期字段,然后将对象编组回 XML。
import javax.xml.bind.*;
import java.io.File;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Foo.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("input.xml");
Foo foo = (Foo) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(foo, System.out);
}
}
输出
下面是 运行 演示代码的输出,我们看到所有值都已正确转换。请注意,Date
和 Calendar
值默认为默认的日期时间表示形式。您可以使用 @XmlSchemaType
注释来控制它。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<foo>
<date>2007-12-12T18:00:00-05:00</date>
<cal>2007-12-13T00:00:00+01:00</cal>
<xgc>2007-12-13+01:00</xgc>
</foo>