提问人:mac 提问时间:5/8/2009 最后编辑:Anonymousmac 更新时间:2/9/2022 访问量:686252
java.util.Date 转换为 XMLGregorianCalendar
java.util.Date to XMLGregorianCalendar
答:
GregorianCalendar c = new GregorianCalendar();
c.setTime(yourDate);
XMLGregorianCalendar date2 = DatatypeFactory.newInstance().newXMLGregorianCalendar(c);
评论
这是将 GregorianCalendar 转换为 XMLGregorianCalendar 的方法;我将把从 java.util.Date 转换为 GregorianCalendar 的部分留给您作为练习:
import java.util.GregorianCalendar;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
public class DateTest {
public static void main(final String[] args) throws Exception {
GregorianCalendar gcal = new GregorianCalendar();
XMLGregorianCalendar xgcal = DatatypeFactory.newInstance()
.newXMLGregorianCalendar(gcal);
System.out.println(xgcal);
}
}
编辑:懒洋洋的:-)
评论
我希望我在这里的编码是正确的;D 为了使它更快,只需使用 GregorianCalendar 的丑陋的 getInstance() 调用而不是构造函数调用:
import java.util.GregorianCalendar;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
public class DateTest {
public static void main(final String[] args) throws Exception {
// do not forget the type cast :/
GregorianCalendar gcal = (GregorianCalendar) GregorianCalendar.getInstance();
XMLGregorianCalendar xgcal = DatatypeFactory.newInstance()
.newXMLGregorianCalendar(gcal);
System.out.println(xgcal);
}
}
评论
GregorianCalendar.getInstance()
Calendar.getInstance()
Calendar.getInstance()
new GregorianCalendar()
ClassCastException
对于那些可能最终在这里寻找相反的转换(从到)的人:XMLGregorianCalendar
Date
XMLGregorianCalendar xcal = <assume this is initialized>;
java.util.Date dt = xcal.toGregorianCalendar().getTime();
只是以为我会在下面添加我的解决方案,因为上面的答案不能满足我的确切需求。我的 Xml 架构需要单独的 Date 和 Time 元素,而不是单个 DateTime 字段。上面使用的标准 XMLGregorianCalendar 构造函数将生成一个 DateTime 字段
请注意,有几个哥特卡,例如必须在月份中添加一个(因为 java 从 0 开始计算月份)。
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(yourDate);
XMLGregorianCalendar xmlDate = DatatypeFactory.newInstance().newXMLGregorianCalendarDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH)+1, cal.get(Calendar.DAY_OF_MONTH), 0);
XMLGregorianCalendar xmlTime = DatatypeFactory.newInstance().newXMLGregorianCalendarTime(cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE), cal.get(Calendar.SECOND), 0);
假设您正在对 xml 进行解码或编码并使用 ,则可以完全替换 dateTime 绑定,并对架构中的每个日期使用“XMLGregorianCalendar”以外的其他内容。JAXB
这样一来,你就可以做重复的事情,同时你可以把时间花在编写提供价值的精彩代码上。JAXB
jodatime 示例:(使用 java.util.Date 执行此操作也可以 - 但有一定的限制。我更喜欢 jodatime,它是从我的代码中复制的,所以我知道它有效......DateTime
<jxb:globalBindings>
<jxb:javaType name="org.joda.time.LocalDateTime" xmlType="xs:dateTime"
parseMethod="test.util.JaxbConverter.parseDateTime"
printMethod="se.seb.bis.test.util.JaxbConverter.printDateTime" />
<jxb:javaType name="org.joda.time.LocalDate" xmlType="xs:date"
parseMethod="test.util.JaxbConverter.parseDate"
printMethod="test.util.JaxbConverter.printDate" />
<jxb:javaType name="org.joda.time.LocalTime" xmlType="xs:time"
parseMethod="test.util.JaxbConverter.parseTime"
printMethod="test.util.JaxbConverter.printTime" />
<jxb:serializable uid="2" />
</jxb:globalBindings>
和转换器:
public class JaxbConverter {
static final DateTimeFormatter dtf = ISODateTimeFormat.dateTimeNoMillis();
static final DateTimeFormatter df = ISODateTimeFormat.date();
static final DateTimeFormatter tf = ISODateTimeFormat.time();
public static LocalDateTime parseDateTime(String s) {
try {
if (StringUtils.trimToEmpty(s).isEmpty())
return null;
LocalDateTime r = dtf.parseLocalDateTime(s);
return r;
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
public static String printDateTime(LocalDateTime d) {
try {
if (d == null)
return null;
return dtf.print(d);
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
public static LocalDate parseDate(String s) {
try {
if (StringUtils.trimToEmpty(s).isEmpty())
return null;
return df.parseLocalDate(s);
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
public static String printDate(LocalDate d) {
try {
if (d == null)
return null;
return df.print(d);
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
public static String printTime(LocalTime d) {
try {
if (d == null)
return null;
return tf.print(d);
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
public static LocalTime parseTime(String s) {
try {
if (StringUtils.trimToEmpty(s).isEmpty())
return null;
return df.parseLocalTime(s);
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
}
请参阅此处:如何按日期替换 XmlGregorianCalendar?
如果您乐于根据时区+时间戳映射到某个时刻,并且原始时区并不真正相关,那么可能也没问题。java.util.Date
使用 Joda-Time 库的一行示例:
XMLGregorianCalendar xgc = DatatypeFactory.newInstance().newXMLGregorianCalendar(new DateTime().toGregorianCalendar());
感谢 Nicolas Mommaerts 在接受的答案中的评论。
看看这个代码:-
/* Create Date Object */
Date date = new Date();
XMLGregorianCalendar xmlDate = null;
GregorianCalendar gc = new GregorianCalendar();
gc.setTime(date);
try{
xmlDate = DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);
}
catch(Exception e){
e.printStackTrace();
}
System.out.println("XMLGregorianCalendar :- " + xmlDate);
您可以在此处查看完整的示例
评论
我想退后一步,以现代的方式看待这个已有10年历史的问题。上面提到的类 和 ,现在已经很旧了。我挑战它们的使用并提供替代方案。Date
XMLGregorianCalendar
Date
总是设计得很差,已经有20多年的历史了。这很简单:不要使用它。XMLGregorianCalendar
也很旧,设计很老式。据我了解,它用于为 XML 文档生成 XML 格式的日期和时间。喜欢或 .这些格式与 ISO 8601 非常吻合,以至于现代 Java 日期和时间 API java.time 的类可以生成它们,这是我们更喜欢的。2009-05-07T19:05:45.678+02:00
2009-05-07T17:05:45.678Z
无需转换
对于许多(大多数?)目的,a 的现代替代品将是 .An 是一个时间点(就像 a 一样)。Date
Instant
Instant
Date
Instant yourInstant = // ...
System.out.println(yourInstant);
此代码片段的示例输出:
2009-05-07T17:05:45.678Z
它与上面的示例字符串中的后者相同。正如你们大多数人所知,它来自被隐式调用。使用 java.time,在许多情况下,我们不需要过去在 、 和其他类之间进行的转换(在某些情况下,我们确实需要转换,不过,我在下一节中将向您展示几个转换)。XMLGregorianCalendar
Instant.toString
System.out.println
Date
Calendar
XMLGregorianCalendar
控制偏移量
a 和 in 都没有时区和 UTC 偏移量。Ben Noland 之前接受的、仍然得票最高的答案使用 JVM 的当前默认时区来选择 .为了在现代对象中包含偏移量,我们使用 .例如:Date
Instant
XMLGregorianCalendar
OffsetDateTime
ZoneId zone = ZoneId.of("America/Asuncion");
OffsetDateTime dateTime = yourInstant.atZone(zone).toOffsetDateTime();
System.out.println(dateTime);
2009-05-07T13:05:45.678-04:00
同样,这符合 XML 格式。如果要再次使用当前 JVM 时区设置,请设置为 。zone
ZoneId.systemDefault()
如果我绝对需要 XMLGregorianCalendar,该怎么办?
还有更多方法可以转换为 。我将介绍一对夫妇,每一种都有其优点和缺点。首先,就像 生成一个字符串一样,它也可以从这样的字符串中构建:Instant
XMLGregorianCalendar
XMLGregorianCalendar
2009-05-07T17:05:45.678Z
String dateTimeString = yourInstant.toString();
XMLGregorianCalendar date2
= DatatypeFactory.newInstance().newXMLGregorianCalendar(dateTimeString);
System.out.println(date2);
2009-05-07T17:05:45.678Z
优点:它很短,我不认为它会给人任何惊喜。缺点:对我来说,将即时格式化为字符串并解析它是一种浪费。
ZonedDateTime dateTime = yourInstant.atZone(zone);
GregorianCalendar c = GregorianCalendar.from(dateTime);
XMLGregorianCalendar date2 = DatatypeFactory.newInstance().newXMLGregorianCalendar(c);
System.out.println(date2);
2009-05-07T13:05:45.678-04:00
优点:这是官方转换。控制偏移量是自然而然的。缺点:它经历了更多的步骤,因此更长。
如果我们有约会呢?
如果您从旧 API 中获得了一个您现在无法更改的老式对象,请将其转换为:Date
Instant
Instant i = yourDate.toInstant();
System.out.println(i);
输出与之前相同:
2009-05-07T17:05:45.678Z
如果要控制偏移量,请以与上述相同的方式进一步转换为 an。OffsetDateTime
如果你有一个老式的,绝对需要一个老式的,只需使用本·诺兰的答案。Date
XMLGregorianCalendar
链接
- Oracle 教程:解释如何使用 java.time 的日期时间。
- W3Schools 上的 XSD 日期和时间数据类型。
- 维基百科文章:ISO 8601
评论
我的解决方案
public static XMLGregorianCalendar DateToXMLGregorianCalendar(Date date) {
GregorianCalendar gregoriancalendar = new GregorianCalendar();
gregoriancalendar.setTime(date);
XMLGregorianCalendar xmlGregorianCalendar = new XMLGregorianCalendarImpl(gregoriancalendar);
return xmlGregorianCalendar;
}
评论
ZonedDateTime