Xml xsd:dateTime无时区的语义及其到日期的转换

Xml xsd:dateTime无时区的语义及其到日期的转换,xml,datetime,jaxb,xsd,timezone,Xml,Datetime,Jaxb,Xsd,Timezone,我有一个关于XML模式的内置类型xsd:dateTime的问题 没有时区的xsd:dateTime的确切语义是什么?例如1970-01-01T00:00:00 我已经阅读了许多XML模式规范文档,但没有找到应该如何处理它 具体来说,我想了解如何正确地将xsd:dateTime转换为Date(比如java.util.Date或JavaScriptDate)对象 旁注:我非常了解Java util类,如DatatypeConverter或DatatypeFactory,我想找到定义如何进行转换的XM

我有一个关于XML模式的内置类型
xsd:dateTime
的问题

没有时区的
xsd:dateTime
的确切语义是什么?例如
1970-01-01T00:00:00

我已经阅读了许多XML模式规范文档,但没有找到应该如何处理它

具体来说,我想了解如何正确地将
xsd:dateTime
转换为Date(比如
java.util.Date
或JavaScript
Date
)对象

旁注:我非常了解Java util类,如
DatatypeConverter
DatatypeFactory
,我想找到定义如何进行转换的XML模式规范

Date
类(在Java和JavaScript中)的问题是这些类确实有时区(默认为本地时区)。如果我得到一个输入上没有时区的
xsd:dateTime
,那么我必须以某种方式决定应该假设哪个时区。否则,我就无法将其转换为时区值(如
Date

现在的问题是,我应该假设什么。我在这里看到以下选项:

  • 假设一些默认值,如UTC
  • 假设处理器的本地时区
我真的不喜欢第二种选择。这完全是随机的!在我的机器上,如果我运行

System.out.println(DATATYPE_FACTORY
    .newXMLGregorianCalendar("1970-01-01T00:00:00")
    .toGregorianCalendar().getTime().getTime());
对于GMT+1、GMT或GMT-1,我将得到-3600000、0、3600000(甚至更多的变体,取决于夏季时间)。这太武断了,我真的不明白。这是否意味着我们有一个包含如下元素的XML文档

<date-time>1970-01-01T00:00:00</date-time>
1970-01-01T00:00:00
我们实际上不知道,瞬间的确切时间是什么意思

第一个选项(假设UTC)对我来说似乎更有效,但这显然不是(至少)Java工具正在做的事情

所以,有人能给我一个指针,指向某种定义无时区的xsd:dateTime的语义的规范吗

多谢各位

更新:

目前的调查结果是:

  • 未指定时区与“未指定”时区的语义完全相同,也就是说,您不能盲目假设UTC或处理器的本地时区或其他任何东西。这是一些本地时区,但您不知道是哪一个
  • 这基本上意味着严格来说,您不能将
    xsd:dateTime
    转换为具有特定时区的Date对象,除非以某种方式对不存在的时区进行假设
  • 作为一个工具提供商,我不能真正做出这样一个有根据的假设。我对数据或其语义没有背景知识
  • 这让我得出结论,工具用户必须提供这样的假设——无论是显式的还是隐式的
我的解决办法如下:

  • 在我的库中,我有一个所谓的
    context
    对象,它提供XML处理上下文(类似于JAXB
    JAXBContext
    )。我将使用
    getDefaultTimezoneOffset()
    setDefaultTimezoneOffset(int timezoneOffset)
  • 默认情况下,此方法将返回一些默认值。我现在更喜欢
    0
    (UTC)。但是也可以是本地时区(就像Java工具一样)
  • 欢迎库用户提供不同的默认时区偏移,但这不是严格要求的(“隐式”假设)
  • xsd:dateTime
    解析为
    Date
    时,如果传入值缺少时区,则假定它是
    上下文。getDefaultTimezoneOffset()
  • 我还将注意解析的日期对象中的传入时区(或缺少该时区)。例如,在类似
    originalTimezoneOffset
    之类的属性中。这不会修改
    日期
    对象的值,但会提供一些额外的上下文信息(例如,何时应再次打印该值)
  • 当打印<代码>日期<代码>时,库将检查<代码>原语TimeTimeOffice ,如果提供,则在呈现词法值时考虑它。

这是我自己使用的。这一切都从规范开始:

“本地”或未分区时间被假定为 根据相关法律规定的某些未指定地点的时区 法律权威;目前没有法律规定的时区 其持续时间大于14小时 每个数值属性(timeOnTimeline除外)的值为 限制在由制造商确定的间隔内的最大值 下一个更高的属性。例如,日值不能为32,并且 对于02月和2002年(2002年2月),甚至不能为29

如果这令人困惑,请转至第3.2.7.2节dateTime上的订单关系

摘录(为了满足此处的发布标准):

两个日期时间p和Q之间的顺序定义如下 算法[…]A.规范化P和Q。也就是说,如果存在时区 存在,但不是Z,将其转换为Z[…]

这些将是相关的:

C.否则,如果p包含时区,而Q不包含时区,则比较为 跟随: 1.如果P<(Q带时区+14:00),则PQ如果P>(Q带时区-14:00) 3.P Q否则,即如果(Q带时区+14:00) D.否则,如果p不包含时区,而Q包含时区,则比较如下 跟随: 1.PQ,如果(带时区的P+14:00)>Q。 3.P Q否则,即如果(P带时区+14:00) 3.2.7中的“幻数”14:

[…]目前没有法律规定的时区是 震级大于14小时的持续时间

当然,您可以在不确定的场景中运行