java.util.Date 和 XMLGregorianCalendar 之间的简单转换
我正在寻找一种在 java.util.Date 和 javax.xml.datatype.XMLGregorianCalendar 之间双向转换的简单方法。
这是我现在使用的代码:
import java.util.GregorianCalendar;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
/**
* Utility class for converting between XMLGregorianCalendar and java.util.Date
*/
public class XMLGregorianCalendarConverter {
/**
* Needed to create XMLGregorianCalendar instances
*/
private static DatatypeFactory df = null;
static {
try {
df = DatatypeFactory.newInstance();
} catch (DatatypeConfigurationException dce) {
throw new IllegalStateException(
"Exception while obtaining DatatypeFactory instance", dce);
}
}
/**
* Converts a java.util.Date into an instance of XMLGregorianCalendar
*
* @param date Instance of java.util.Date or a null reference
* @return XMLGregorianCalendar instance whose value is based upon the
* value in the date parameter. If the date parameter is null then
* this method will simply return null.
*/
public static XMLGregorianCalendar asXMLGregorianCalendar(java.util.Date date) {
if (date == null) {
return null;
} else {
GregorianCalendar gc = new GregorianCalendar();
gc.setTimeInMillis(date.getTime());
return df.newXMLGregorianCalendar(gc);
}
}
/**
* Converts an XMLGregorianCalendar to an instance of java.util.Date
*
* @param xgc Instance of XMLGregorianCalendar or a null reference
* @return java.util.Date instance whose value is based upon the
* value in the xgc parameter. If the xgc parameter is null then
* this method will simply return null.
*/
public static java.util.Date asDate(XMLGregorianCalendar xgc) {
if (xgc == null) {
return null;
} else {
return xgc.toGregorianCalendar().getTime();
}
}
}
有没有更简单的东西,比如我忽略的一些 API 调用?
在标准 XML 日期/时间和 Java 之间进行转换date 对象似乎是一个非常常规的任务,我很惊讶我必须编写这段代码。
有什么建议吗?
注释: 我的 JAXB 类是从架构自动生成的。我的项目的构建过程不允许我对生成的类进行手动更改。 xs:dateTime 元素由 XJC 作为 JAXB 类中的 XMLGregorianCalendar 生成。该架构会定期扩展和调整,因此我可以对架构 XSD 文件进行有限的更改。
解决方案更新: Blaise 提出的解决方案使我能够将 XMLGregorianCalendar 从混合中取出并处理 java.util.Calendar 对象。通过在模式文件顶部添加 JAXB 绑定子句,XJC 能够为我的 JAXB 类中的 xs:dateTime 生成更合适的映射。以下是一些显示我的 XSD 文件中的修改的片段。
XSD 文件中的根元素:
<xs:schema xmlns:mydata="http://my.example.com/mydata" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" targetNamespace="http://my.example.com/mydata" elementFormDefault="unqualified" attributeFormDefault="unqualified" version="0.2" xml:lang="en" jaxb:version="2.0">
JAXB 绑定注释块,立即插入到 XSD 中的根元素之后:
<xs:annotation>
<xs:appinfo>
<jaxb:globalBindings>
<jaxb:javaType name="java.util.Calendar" xmlType="xs:dateTime" parseMethod="javax.xml.bind.DatatypeConverter.parseDateTime" printMethod="javax.xml.bind.DatatypeConverter.printDateTime" />
</jaxb:globalBindings>
</xs:appinfo>
</xs:annotation>
由于 XML xs:dateTime 字段还存储时区,因此可能会更好无论如何,我都可以使用日历而不是日期,因为日历对象有一个非常好的 API 来处理区域设置和时区。无论如何,我更乐意处理 Calendar 对象而不是 XMLGregorianCalendar。不再需要我上面列出的转换方法。我没有一直到达 java.util.Date,但已经足够接近了!
I'm looking for a simple method of converting between java.util.Date and javax.xml.datatype.XMLGregorianCalendar in both directions.
Here is the code that I'm using now:
import java.util.GregorianCalendar;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
/**
* Utility class for converting between XMLGregorianCalendar and java.util.Date
*/
public class XMLGregorianCalendarConverter {
/**
* Needed to create XMLGregorianCalendar instances
*/
private static DatatypeFactory df = null;
static {
try {
df = DatatypeFactory.newInstance();
} catch (DatatypeConfigurationException dce) {
throw new IllegalStateException(
"Exception while obtaining DatatypeFactory instance", dce);
}
}
/**
* Converts a java.util.Date into an instance of XMLGregorianCalendar
*
* @param date Instance of java.util.Date or a null reference
* @return XMLGregorianCalendar instance whose value is based upon the
* value in the date parameter. If the date parameter is null then
* this method will simply return null.
*/
public static XMLGregorianCalendar asXMLGregorianCalendar(java.util.Date date) {
if (date == null) {
return null;
} else {
GregorianCalendar gc = new GregorianCalendar();
gc.setTimeInMillis(date.getTime());
return df.newXMLGregorianCalendar(gc);
}
}
/**
* Converts an XMLGregorianCalendar to an instance of java.util.Date
*
* @param xgc Instance of XMLGregorianCalendar or a null reference
* @return java.util.Date instance whose value is based upon the
* value in the xgc parameter. If the xgc parameter is null then
* this method will simply return null.
*/
public static java.util.Date asDate(XMLGregorianCalendar xgc) {
if (xgc == null) {
return null;
} else {
return xgc.toGregorianCalendar().getTime();
}
}
}
Is there anything simpler, like some API call that I have overlooked?
Converting between a standard XML date/time and a Java date object seems like a pretty routine task and I'm surprised that I have to write this code at all.
Any suggestions?
NOTES:
My JAXB classes are autogenerated from a schema. The build process on my project does not allow for me to make manual changes to the generated classes. The xs:dateTime elements are being generated by XJC as XMLGregorianCalendar in the JAXB classes. The schema is extended and tweaked periodically, so I am allowed to make limited changes to the schema XSD file.
UPDATE ON SOLUTION:
The solution proposed by Blaise has allowed me to take XMLGregorianCalendar out of the mix and deal with java.util.Calendar objects instead. By adding a JAXB binding clause at the top of my schema file, XJC is able to generate more appropriate mappings for xs:dateTime in my JAXB classes. Here are some snippets that show the modifications in my XSD file.
The root element in the XSD file:
<xs:schema xmlns:mydata="http://my.example.com/mydata" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" targetNamespace="http://my.example.com/mydata" elementFormDefault="unqualified" attributeFormDefault="unqualified" version="0.2" xml:lang="en" jaxb:version="2.0">
JAXB binding annotation block, inserted immediately after root element in XSD:
<xs:annotation>
<xs:appinfo>
<jaxb:globalBindings>
<jaxb:javaType name="java.util.Calendar" xmlType="xs:dateTime" parseMethod="javax.xml.bind.DatatypeConverter.parseDateTime" printMethod="javax.xml.bind.DatatypeConverter.printDateTime" />
</jaxb:globalBindings>
</xs:appinfo>
</xs:annotation>
Since the XML xs:dateTime field also stores timezone, it might be better for me to work with Calendar instead of Date anyway since Calendar objects have a pretty good API for working with locales and timezones. In any case, I'm much happier to deal with Calendar objects instead of XMLGregorianCalendar. No need for the conversion methods that I listed above anymore. I didn't get all the way to java.util.Date, but close enough!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
从 XMLGregorianCalendar 到 java.util.Date 您可以简单地执行以下操作:
From XMLGregorianCalendar to java.util.Date you can simply do:
为什么不使用外部绑定文件来告诉 XJC 生成 java.util.Date 字段而不是 XMLGregorianCalendar?
另请参阅
如何将 xs:date 映射到 java.util.Date?博客
Why not use an external binding file to tell XJC to generate java.util.Date fields instead of XMLGregorianCalendar?
Also see
How do I map xs:date to java.util.Date? Blog
从 java.util.Date 到 XMLGregorianCalendar 您可以简单地执行以下操作:
在 @f-puras 的第一个注释后编辑代码,因为我犯了一个错误。
From java.util.Date to XMLGregorianCalendar you can simply do:
Code edited after the first comment of @f-puras, by cause i do a mistake.
我必须进行一些更改才能使其工作,因为同时有些事情似乎已经发生了变化:
这是一个工作示例,希望这有所帮助(我正在使用 JodaTime,但在本例中 SimpleDate 就足够了):
在 xsd 中,我遵循了上面给出的优秀参考资料,因此我包含了以下 xml 注释:
I had to make some changes to make it work, as some things seem to have changed in the meantime:
Here's a working example, hope this helps (I'm using JodaTime but in this case SimpleDate would be sufficient):
In the xsd, I have followed the excellent references given above, so I have included this xml annotation:
我也有过这样的头痛。
通过在我的 POJO 中简单地将时间字段表示为原始 long 来摆脱它。
现在,我的 WS 客户端代码的生成可以正确处理所有内容,不再有 XML 到 Java 的垃圾。当然,在 Java 端处理 millis 是简单且轻松的。
KISS 原则很震撼!
I too had this kind of headache.
Got rid of of it by simply representing time fields as primitive long in my POJO.
Now the generation of my WS client code handle everything correctly and no more XML-to-Java crap. And of course dealing with millis on the Java side is simple and painless.
KISS principle rocks!
您可以使用此自定义将默认映射更改为 java.util.Date
You can use the this customization to change the default mapping to java.util.Date
在编组时自定义日历和日期
第 1 步:为自定义属性准备 jaxb 绑定 xml,在本例中,我准备了日期和日历
Setp 2:将自定义 jaxb 绑定文件添加到 Apache 或 xsd 选项中的任何相关插件,如下所述
Setp 3:编写 CalendarConverter 类的代码
Setp 4:输出
Customizing the Calendar and Date while Marshaling
Step 1 : Prepare jaxb binding xml for custom properties, In this case i prepared for date and calendar
Setp 2 : Add custom jaxb binding file to Apache or any related plugins at xsd option like mentioned below
Setp 3 : write the code for CalendarConverter class
Setp 4 : Output