Java XMLGregorianCalendar到GregorianCalendar
我只是尝试使用下面的代码将(从JAXWS获得的)的实例转换为特定时区的实例 日期是在美国东部时间,我想把它转换成格林尼治标准时间进一步保存到数据库Java XMLGregorianCalendar到GregorianCalendar,java,date,timezone,Java,Date,Timezone,我只是尝试使用下面的代码将(从JAXWS获得的)的实例转换为特定时区的实例 日期是在美国东部时间,我想把它转换成格林尼治标准时间进一步保存到数据库 //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.toGregor
//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);
输出: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.ZoneInfo[id=“UTC”,offset=0,dstSaves=0,useDaylight=false,transitions=0,lastRule=null],周的第一天=1,周的第一天=1,纪元=1,年=2016,月=6,年的周=29,月的周=3,月的日=12,年的日=194,周的日=3,周的日=2,上午下午=1,小时=11,日的小时=23,分钟=57,秒=21,毫秒=0,分区偏移量=-14400000,DST偏移量=0]
任何帮助都将不胜感激 记住Java对象没有时区。它们在UTC内部。时区仅在打印(格式化)时显示
这个简单的代码可以工作:
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),那么您需要一个
现在您可以将它作为一个使用.< /P>< P>作为另一个路径,您可以考虑使用DATE来代替代码中的XMLGReGrangRANDANARS,使用JAXB绑定,如堆栈溢出问题中所讨论的。 tl;博士 java.time 您正在使用可怕的旧日期时间类,这些类在几年前被JSR310中定义的现代java.time类所取代
将XMLGregorianCalendar实例(我从JAXWS获得)转换为GregorianCalendar 第一个电话 从传统类gregorianalendar
转换为现代类java.time.ZonedDateTime
。添加到旧类中
ZonedDateTime zdt = gc.toZonedDateTime() ;
日期是在美国东部时间,我想把它转换成格林尼治标准时间
java.time.Instant
类表示一个时刻,始终以UTC为单位。您可以从中提取。相同的时刻,不同的挂钟时间
Instant instant = zdt.toInstant() ;
用于进一步保存到数据库
//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);
如果您的JDBC驱动程序支持,您可以向数据库传递一个即时。在JDBC4.2中,Instant
类型是可选的
myPreparedStatement.setObject( … , instant ) ;
如果不受支持,请使用OffsetDateTime
,因为JDBC 4.2需要支持
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
myPreparedStatement.setObject( … , odt ) ;
检索
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
美国东部时间快到了
EST
不是实时时区
以大陆/地区
的格式指定,例如美国/蒙特利尔
,非洲/卡萨布兰卡
,或太平洋/奥克兰
。切勿使用2-4个字母的缩写,如EST
或IST
,因为它们不是真正的时区,也不是标准化的,甚至不是唯一的(!)
我使用以下代码将XMLGregorianCalendar
从具有给定时区(例如GMT+0)的给定源转换为具有当前系统时区的GregorianCalendar
:
GregorianCalendar.from(xmlGregorianCalendar
.toGregorianCalendar()
.toZonedDateTime()
.withZoneSameInstant(ZoneId.systemDefault()))
仅使用xmlgoriancalendar.toGregorianCalendar()
时,返回的GregorianCalendar
与源系统具有相同的时区,而不是当前系统的时区在接收数据时转换时区更安全:这样可以减少代码中潜在问题的数量,因为所有日期都基于系统时区
例如:
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)
如果输入是04:43:54
,那么输出怎么可能是05:27:21
?时区更改不会影响秒数。抱歉,我错误地添加了错误的输出。更正了now.FYI,非常麻烦的日期时间类,如和java.text.simpleDataFormat
,现在被java 8和更高版本中内置的类所取代。请参阅。使用此xmlCal.toGregorianCalendar().getTimeInMillis()
无法解决此问题,因为这是使用默认服务器时区。但是我想把日期保存到格林尼治标准时间,所以我用的是这个xmlCal.toGregorianCalendar(TimeZone.getTimeZone(“UTC”),Locale.US,null).getTime()
但这不起作用。@bbajajxmlCal.toGregorianCalendar().getTimeInMillis()
不使用默认的服务器时区。gregoriacalendar
将从xmlgoriiancalendar
继承时区,该时区使用输入字符串中的时区(-04:00
)。时间戳
值没有时区。它的内部值始终以UTC为单位。调用date.toString()。date
的值是自UTC纪元(即1970年1月1日)起的毫秒数。
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
GregorianCalendar.from(xmlGregorianCalendar
.toGregorianCalendar()
.toZonedDateTime()
.withZoneSameInstant(ZoneId.systemDefault()))
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)