Reputation: 33
I want to add 5 days delay to XMLGregorianCalendar date (date is coming from json request). I tried converting it first to LocalDateTime as follows, this works
LocalDateTime date = request.getDate().toGregorianCalendar().toZonedDateTime().toLocalDateTime().plusDays(5);
Timestamp ts = Timestamp.valueOf(date);
Another approach I tried was as follows, which is throwing below error
Timestamp date = DateUtil.convertToTimestamp(request.getDate().
add(DatatypeFactory.newInstance().newDuration("P14D"));
Error:
Required type: XMLGregorianCalendar
Provided: void
Although, the LocalDateTime one does not give any errors, I am just wondering if there's an easy way to do this. Any help would be appreciated. Thanks in advance!
Upvotes: 0
Views: 91
Reputation: 338181
XMLGregorianCalendar ➡️ GregorianCalendar ➡️ ZonedDateTime ➡️ OffsetDateTime
myPreparedStatement
.setObject(
… ,
myXMLGregorianCalendar
.toGregorianCalendar()
.toZonedDateTime()
.plusDays( 5 )
.toOffsetDateTime()
)
When handed a legacy date-time object like XMLGregorianCalendar
, immediately convert to the modern java.time classes. In java.time, the replacement class is ZonedDateTime
.
To get to ZonedDateTime
, go though another legacy class, GregorianCalendar
.
ZonedDateTime zdt = myXMLGregorianCalendar.toGregorianCalendar().toZonedDateTime() ;
Add five days. Adjustments are automatically made for anomalies such as Daylight Saving Time (DST).
ZonedDateTime fiveDaysLater = zdt.plusDays( 5 ) ;
LocalDateTime
is not a momentDo not use LocalDateTime
at all in this situation. That class lacks the context of an offset or time zone, so it cannot be used to represent a moment, a specific point on the timeline.
If you are trying to write this value to a database, do not use the legacy Timestamp
class. Use only java.time classes. To communicate a moment to a database, use java.time.OffsetDateTime
.
OffsetDateTime odt = fiveDaysLater.toOffsetDateTime() ;
myPreparedStatement.setObject( … , odt ) ;
Retrieval.
OffsetDateTime odt = myResultSet.getObject ( … , OffsetDateTime.class ) ;
ZoneId zoneId = ZoneId.of( "Asia/Tokyo"" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( zoneId ) ;
Upvotes: 1
Reputation: 44292
Don’t use the Timestamp class. It doesn’t do what you think it does. In fact, it doesn’t even do what it was originally intended to do all that well (represent a particular SQL type).
Just use the add method of GregorianCalendar:
XMLGregoriantCalendar xcal = request.getDate();
GregorianCalendar gcal = xcal.toGregorianCalendar();
gcal.add(Calendar.DATE, 5);
xcal = DatatypeFactory.newInstance().newXMLGregorianCalendar(gcal);
Upvotes: 0