首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >XMLGregorianCalendar到GregorianCalendar

XMLGregorianCalendar到GregorianCalendar
EN

Stack Overflow用户
提问于 2016-08-31 20:44:08
回答 4查看 6.9K关注 0票数 3

我只是尝试使用下面的代码将XMLGregorianCalendar实例(从JAXWS获得)转换为特定TimeZone中的GregorianCalendar

EST的日期即将到来,我想将其转换为GMT,以便进一步保存到DB。

代码语言:javascript
复制
//soap response <ns4:TimeStamp>2016-06-18T04:43:54-04:00</ns4:TimeStamp>
//dtime is what i got from JAXB for the above date, so I wrote::
Date date = dTime.toGregorianCalendar(TimeZone.getTimeZone("UTC"), Locale.US, null).getTime();
System.out.println(date);

输出:Sat Jun 18 14:13:54 IST 2016

由于上面没有预期的效果,所以我尝试了DateFormat并给出了预期的结果。

代码语言:javascript
复制
    DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
    df.setTimeZone(TimeZone.getTimeZone("UTC"));

    GregorianCalendar gc =  dTime.toGregorianCalendar();
    System.out.println(df.format(gc.getTime()));

输出:2016-06-18 08:43:54 +0000

如果toGregorianCalendar(...)没有给出预期的结果,这里会有什么问题呢?

我还注意到,上面从toGregorianCalendar获得的GregorianCalendar实例具有fieldSet= false。不确定这是否是造成问题的原因。

java.util.GregorianCalendar[time=1468382241000,areFieldsSet=false,areAllFieldsSet=false,lenient=true,zone=sun.util.calendar.ZoneInfoid="UTC",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null,firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2016,MONTH=6,ERA=1,MONTH=6,ERA=1,firstDayOfWeek=1,ZONE_偏移=-14400000,]

任何帮助都将不胜感激!

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2016-08-31 21:00:16

请记住,Java对象没有时区。他们在世界协调时的内部。时区仅在打印(格式化)时显示。

这个简单的代码工作:

代码语言:javascript
复制
XMLGregorianCalendar xmlCal = XMLGregorianCalendarImpl.parse("2016-06-18T04:43:54-04:00");
GregorianCalendar cal = xmlCal.toGregorianCalendar();
java.util.Date date = cal.getTime();

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
format.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(format.format(date)); // prints: 2016-06-18 08:43:54

因为您的目标是将其保存到数据库中,所以您实际上并不关心将其格式化为文本。假设您使用的是JDBC (而不是一些NoSQL),那么您需要一个Timestamp

代码语言:javascript
复制
XMLGregorianCalendar xmlCal = XMLGregorianCalendarImpl.parse("2016-06-18T04:43:54-04:00");
GregorianCalendar cal = xmlCal.toGregorianCalendar();
java.sql.Timestamp date = new java.sql.Timestamp(cal.getTimeInMillis());

现在,您可以使用PreparedStatement将其交给setTimestamp()

票数 1
EN

Stack Overflow用户

发布于 2019-07-25 04:41:16

tl;dr

代码语言:javascript
复制
myPreparedStatement
.setObject(                     // Exchange java.time objects with your database in JDBC 4.2 and later.
    … ,                         // Specify which `?` placeholder in your SQL statement.
    myXMLGregorianCalendar      // A legacy class. Better to use *java.time* whenever possible.
    .toGregorianCalendar()      // Convert from the one legacy class to another, as a bridge towards the modern `ZonedDateTime` class.
    .toZonedDateTime()          // Convert to the modern class.
    .toInstant()                // Adjust from a time zone to UTC. Same moment, same point on the timeline, different wall-clock time.
    .atOffset(                  // Adjust from basic `Instant` class to the more flexible `OffsetDateTime` class, if your JDBC driver does not offer the optional support for `Instant`. 
        ZoneOffset.UTC          // Specify UTC using this constant.
    )                           // Returns a `OffsetDateTime` object.
)

java.time

您正在使用多年前被JSR 310中定义的现代java.time类取代的可怕的旧日期时间类。

将XMLGregorianCalendar实例(我从JAXWS获得)转换为GregorianCalendar

先打电话给XMLGregorianCalendar::toGregorianCalendar()

代码语言:javascript
复制
GregorianCalendar gc = myXMLGregorianCalendar.toGregorianCalendar() ;

将遗留类GregorianCalendar转换为现代java.time.ZonedDateTime调用新的转换方法添加到了旧类中。

代码语言:javascript
复制
ZonedDateTime zdt = gc.toZonedDateTime() ;

我想把它转换成格林尼治标准时间

java.time.Instant类表示UTC中的某个时刻,总是在UTC中。您可以从Instant中提取ZonedDateTime。同样的时刻,不同的挂钟时间。

代码语言:javascript
复制
Instant instant = zdt.toInstant() ;

以便进一步保存到DB

如果您的JDBC驱动程序支持Instant,您可以将一个JDBC传递给数据库。在JDBC4.2中,Instant类型是可选的。

代码语言:javascript
复制
myPreparedStatement.setObject( … , instant ) ;

如果不支持,则使用OffsetDateTime作为JDBC4.2所需的支持。

代码语言:javascript
复制
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
myPreparedStatement.setObject( … , odt ) ;

检索。

代码语言:javascript
复制
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;

美国东部时间就要到了

EST不是一个实时时区。

Continent/Region格式指定Continent/Region,如America/MontrealAfrica/CasablancaPacific/Auckland。不要使用2-4字母的缩写,如ESTIST,因为它们不是真正的时区,不标准化,甚至不是唯一的(!)。

代码语言:javascript
复制
ZoneId z = ZoneId.of( "America/Montreal" ) ;  
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;

票数 2
EN

Stack Overflow用户

发布于 2021-03-08 15:34:39

我使用以下代码将XMLGregorianCalendar从具有给定时区(例如GMT+0)的给定源转换为具有当前系统时区的GregorianCalendar

代码语言:javascript
复制
GregorianCalendar.from(xmlGregorianCalendar
    .toGregorianCalendar()
    .toZonedDateTime()
    .withZoneSameInstant(ZoneId.systemDefault()))

仅使用XMLGregorianCalendar.toGregorianCalendar()时,返回的GregorianCalendar具有与源系统相同的时区,而不是当前系统的时区。当您收到数据时,转换时区是更安全的:这样,可以减少代码中潜在问题的数量,因为所有日期都基于系统时区。

例如:

代码语言:javascript
复制
XMLGregorianCalendar xmlGregorianCalendarFromSource = DatatypeFactory.newInstance()
    .newXMLGregorianCalendar("1983-09-30T23:00:00.000Z"); // the source system is on GMT+0
GregorianCalendar gregorianCalendarWithSourceTZ = xmlGregorianCalendarFromSource.toGregorianCalendar();
GregorianCalendar gregorianCalendarWithSystemTZ = GregorianCalendar.from(xmlGregorianCalendarFromSource 
    .toGregorianCalendar()
    .toZonedDateTime()
    .withZoneSameInstant(ZoneId.systemDefault()));
System.out.println(xmlGregorianCalendarFromSource); // displays "1983-09-30T23:00:00.000Z" (i.e. GMT+0)
System.out.println(gregorianCalendarWithSourceTZ.toZonedDateTime()); // displays "1983-09-30T23:00Z[GMT]" (i.e. GMT+0)
System.out.println(gregorianCalendarWithSystemTZ.toZonedDateTime()); // displays "1983-10-01T00:00+01:00[Europe/Berlin]" (my system timezone is GMT+1 or GMT+2 depending on daylight saving)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39258679

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档