我只是尝试使用下面的代码将XMLGregorianCalendar实例(从JAXWS获得)转换为特定TimeZone中的GregorianCalendar。
EST的日期即将到来,我想将其转换为GMT,以便进一步保存到DB。
//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并给出了预期的结果。
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,]
任何帮助都将不胜感激!
发布于 2016-08-31 21:00:16
请记住,Java对象没有时区。他们在世界协调时的内部。时区仅在打印(格式化)时显示。
这个简单的代码工作:
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。
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()。
发布于 2019-07-25 04:41:16
tl;dr
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()。
GregorianCalendar gc = myXMLGregorianCalendar.toGregorianCalendar() ;将遗留类GregorianCalendar转换为现代java.time.ZonedDateTime。调用新的转换方法添加到了旧类中。
ZonedDateTime zdt = gc.toZonedDateTime() ;我想把它转换成格林尼治标准时间
java.time.Instant类表示UTC中的某个时刻,总是在UTC中。您可以从Instant中提取ZonedDateTime。同样的时刻,不同的挂钟时间。
Instant instant = zdt.toInstant() ;以便进一步保存到DB
如果您的JDBC驱动程序支持Instant,您可以将一个JDBC传递给数据库。在JDBC4.2中,Instant类型是可选的。
myPreparedStatement.setObject( … , instant ) ;如果不支持,则使用OffsetDateTime作为JDBC4.2所需的支持。
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
myPreparedStatement.setObject( … , odt ) ;检索。
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;美国东部时间就要到了
EST不是一个实时时区。
以Continent/Region格式指定Continent/Region,如America/Montreal、Africa/Casablanca或Pacific/Auckland。不要使用2-4字母的缩写,如EST或IST,因为它们不是真正的时区,不标准化,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;

发布于 2021-03-08 15:34:39
我使用以下代码将XMLGregorianCalendar从具有给定时区(例如GMT+0)的给定源转换为具有当前系统时区的GregorianCalendar:
GregorianCalendar.from(xmlGregorianCalendar
.toGregorianCalendar()
.toZonedDateTime()
.withZoneSameInstant(ZoneId.systemDefault()))仅使用XMLGregorianCalendar.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)https://stackoverflow.com/questions/39258679
复制相似问题