Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java XMLGregorianCalendar到GregorianCalendar_Java_Date_Timezone - Fatal编程技术网

Java XMLGregorianCalendar到GregorianCalendar

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

我只是尝试使用下面的代码将(从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.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()
但这不起作用。@bbajaj
xmlCal.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)