Get Date from a DataObject (SDO) without losing the hour (JAVA) - java

I'm trying to get a date from a DataObject (Service Date Object (SDO)) that comes to me as an input and insert it into an Oracle database. The problem has been that the Date I get does not seem to have the introduced hour.
I am using the setDate() method from DataObject with the following value: 2019-05-22T13:30:00Z.
For some reason, when using getDate() what is returning is the day entered with the hour set at 0 (2019-05-22 00:00:00).
I'm not sure if it's due to the input format or something related to the Date class from java.utils.
An easy solution would be to pass it as String and convert it into Date using a format but I would like to save this intermediate step.

java.util.Date versus java.sql.Date
Your Question does not provide enough detail to know for sure, but I can take an educated guess.
returning is the day entered with the hour set at 0 (2019-05-22 00:00:00).
I suspect your code calling setDate and/or getDate is using a java.sql.Date object rather than a java.util.Date object.
➥ Check your import statements. If you used the wrong class by accident, that would explain the time-of-day getting set to 00:00.
java.util.Date represents a moment in UTC (a date, a time-of-day, and an offset-from-UTC of zero hours-minutes-seconds).
java.sql.Date pretends to represent a date-only, without a time-of-day and without a time zone or offset-from-UTC. Actually does contain a time-of-day and offset, but tries to adjust the time to 00:00:00.0 as part of the pretense.
Confusing? Yes. These old date-time classes from the earliest days of Java are a bloody awful mess, built by people who did not understand the complexities of date-time handling. Avoid these legacy date-time classes!
These legacy classes were supplanted years ago by the modern java.time classes defined in JSR 310. Try to do all your work in java.time. When interoperating with old code such as SDO that is not yet updated for java.time, call on new conversion methods added to the old classes.
The modern replacement of a java.util.Date is java.time.Instant. Both represents a moment in UTC, though Instant has a finer resolution of nanoseconds versus milliseconds.
Instant instant = Instant.now() ; // Capture the current moment in UTC.
Convert from modern class to legacy class. Beware of data-loss: Any microseconds or nanoseconds in the fractional second are truncated to milliseconds (as noted above).
java.util.Date d = java.util.Date.from( instant ) ; // Convert from modern to legacy. Truncates any microseconds or nanoseconds.
Pass to your SDO object.
mySdoDataObject.setDate( d ) ;
Going the other direction, retrieve the legacy java.util.Date object and immediately convert to an Instant.
Instant instant = mySdoDataObject.getDate().toInstant() ;
To see that same moment through the wall-clock time used by the people of a particular region (a time zone), apply a ZoneId to get a ZonedDateTime object.
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, same point on the timeline, different wall-clock time.
An easy solution would be to pass it as String
No! Use smart objects, not dumb strings. We have the industry-leading date-time library built into Java, so use it.
Database
As of JDBC 4.2, we can directly exchange java.time objects with the database.
Your JDBC driver may optionally handle Instant. If not, convert to OffsetDateTime.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
myPreparedStatement.setObject( … , odt ) ;
Retrieval.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
Instant instant = odt.toInstant() ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Related

Inserting into database a datetime with the current UTC time

I'm attempting to insert a datetime into a mysql database for the current UTC time via the GETUTCDATE() function in sql. It's failing with "FUNCTION GETUTCDATE DOES NOT EXIST".
Is a way for me to get the current UTC time in sql datetime format from Java, and simply insert it as a string?
Another big issue I'm having is I need to convert the above utc datetime object into local time zones and I don't really know how to do that through standard java api's.
tl;dr
myPreparedStatement // Using a `PreparedStatement` avoids SQL-injection security risk.
.setObject( // As of JDBC 4.2, we can exchange java.time objects with a database via `getObject`/`setObject` methods.
… , // Indicate which `?` placeholder in your SQL statement.
OffsetDateTime.now( ZoneOffset.UTC ) // Capture the current moment in UTC.
) ;
java.time
The modern solution uses the java.time classes that years ago supplanted the terrible old date-time classes.
Get the current moment in UTC using OffsetDateTime.
OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;
MySQL 8.0 uses a resolution of microseconds, for six decimal places in a fractional second. The java.time classes carry a finer resolution of nanoseconds. So you may want to truncate any existing nanos from your OffsetDateTime. Specify your desired resolution with ChronoUnit.
OffsetDateTime odt =
OffsetDateTime
.now(
ZoneOffset.UTC
)
.truncatedTo( ChronoUnit.MICROS )
;
Send to your database via a PreparedStatement to a column of a type akin to the SQL-standard TIMESTAMP WITH TIME ZONE data type. For MySQL 8.0, that would be the type TIMESTAMP.
myPreparedStatement.setObject( … , odt ) ;
And retrieval via a ResultSet.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
To see this moment through the lens of the wall-clock time used by the people of a particular region (a time zone), apply a ZoneId to get a ZonedDateTime object.
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ; // Same moment, same point on the timeline, different wall-clock time.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
You can do it as follows:
OffsetDateTime utc = OffsetDateTime.now(ZoneOffset.UTC);
String sql_date = utc.format(DateTimeFormatter.ofPattern("MM/dd/yyyy")); //here, you can change the format of SQL date as you need
You would need to import the classes as follows:
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
Hope it helps.

Timestamp.from not heeding timezone from Instant

When I try to convert a ZonedDateTime to a Timestamp everything is fine until I call Timestamp.from() in the following code:
ZonedDateTime currentTimeUTC = ZonedDateTime.now(ZoneOffset.UTC);
currentTimeUTC = currentTimeUTC.minusSeconds(currentTimeUTC.getSecond());
currentTimeUTC = currentTimeUTC.minusNanos(currentTimeUTC.getNano());
return Timestamp.from(currentTimeUTC.toInstant());
ZonedDateTime.now(ZoneOffset.UTC); -> 2018-04-26T12:31Z
currentTimeUTC.toInstant() -> 2018-04-26T12:31:00Z
Timestamp.from(currentTimeUTC.toInstant()) -> 2018-04-26 14:31:00.0
// (with Timezone of Europe/Berlin, which is currently +2)
Why is Timestamp.from() not heeding the timezone set in the instant?
The Instant class doesn't have a timezone, it just has the values of seconds and nanoseconds since unix epoch. A Timestamp also represents that (a count from epoch).
why is the debugger displaying this with a Z behind it?
The problem is in the toString methods:
Instant.toString() converts the seconds and nanoseconds values to the corresponding date/time in UTC - hence the "Z" in the end - and I believe it was made like that for convenience (to make the API more "developer-friendly").
The javadoc for toString says:
A string representation of this instant using ISO-8601 representation.
The format used is the same as DateTimeFormatter.ISO_INSTANT.
And if we take a look at DateTimeFormatter.ISO_INSTANT javadoc:
The ISO instant formatter that formats or parses an instant in UTC, such as '2011-12-03T10:15:30Z'
As debuggers usually uses the toString method to display variables values, that explains why you see the Instant with "Z" in the end, instead of the seconds/nanoseconds values.
On the other hand, Timestamp.toString uses the JVM default timezone to convert the seconds/nanos values to a date/time string.
But the values of both Instant and Timestamp are the same. You can check that by calling the methods Instant.toEpochMilli and Timestamp.getTime, both will return the same value.
Note: instead of calling minusSeconds and minusNanos, you could use the truncatedTo method:
ZonedDateTime currentTimeUTC = ZonedDateTime.now(ZoneOffset.UTC);
currentTimeUTC = currentTimeUTC.truncatedTo(ChronoUnit.MINUTES);
This will set all fields smaller than ChronoUnit.MINUTES (in this case, the seconds and nanoseconds) to zero.
You could also use withSecond(0) and withNano(0), but in this case, I think truncatedTo is better and more straight to the point.
Note2: the java.time API's creator also made a backport for Java 6 and 7, and in the project's github issues you can see a comment about the behaviour of Instant.toString. The relevant part to this question:
If we were really hard line, the toString of an Instant would simply be the number of seconds from 1970-01-01Z. We chose not to do that, and output a more friendly toString to aid developers
That reinforces my view that the toString method was designed like this for convenience and ease to use.
Instant does not hold the Timezone information. It only holds the seconds and nanos.
To when you convert your ZonedDateTime into an Instant the information is lost.
When converting into Timestamp then the Timestamp will hold the default Timezone, which is, in your case, Europe/Berlin.
tl;dr
You are being confused by the unfortunate behavior of Timestamp::toString to apply the JVM’s current default time zone to the objects internal UTC value.
➡ Use Instant, never Timestamp.
A String such as 2018-04-26T12:31Z is in standard ISO 8601 format, with the Z being short for Zulu and meaning UTC.
Your entire block of code can be replaced with:
Instant.now()
…such as:
myPreparedStatement.setObject( … , Instant.now() ) ;
Details
The Answer by wowxts is correct. Instant is always in UTC, as is Timestamp, yet Timestamp::toString applies a time zone. This behavior is one of many poor design choices in those troubled legacy classes.
I'll add some other thoughts.
Use Instant for UTC
ZonedDateTime currentTimeUTC = ZonedDateTime.now(ZoneOffset.UTC);
While technically correct, this line is semantically wrong. If you want to represent a moment in UTC, use Instant class. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Instant instant = Instant.now() ; // Capture the current moment in UTC.
Avoid legacy Timestamp class
Timestamp.from(currentTimeUTC.toInstant());
While technically correct, using my suggest above, that would be:
Timestamp.from( instant ); // Convert from modern *java.time* class to troublesome legacy date-time class using new method added to the old class.
Nothing is lost going between Instant and Timestamp, as both represent a moment in UTC with a resolution of nanoseconds. However…
No need to be using java.sql.Timestamp at all! That class is part of the troublesome old date-time classes that are now legacy. They were supplanted entirely by the java.time classes defined by JSR 310. Timestamp is replaced by Instant.
JDBC 4.2
As of JDBC 4.2 and later, you can directly exchange java.time objects with your database.
Insert/Update.
myPreparedStatement.setObject( … , instant ) ;
Retrieval.
Instant instant = myResultSet.getObject( … , Instant.class ) ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

SQL database (JDBC): A column of type date only stores date values and not time values

I have a database like this where lastEdited is a date field.
I connected this database to a Java web application by using "RESTFUL web-services from database"
This automatically generated a class called ThreadChat for my THREADCHAT column. Given here is the getter and setter for the lastEdited part.
lastEdited is a java.util.Date object.
public Date getLastedited() {
return lastedited;
}
public void setLastedited(Date lastedited) {
this.lastedited = lastedited;
}
Here, I am creating a new ThreadChat object and adding the data to the database. Argument for lastEdited is a java.util.Date object.
ThreadChat thread = new ThreadChat(threadName, new Date(), loginIdInt);
threadChatFacadeREST.create(thread);
This would update the table like this.
This method returns all the records in the THREADCHAT table.
List<ThreadChat> list = getAllThreads();
However, getLastEdited() returns a XMLGregorianCalender object instead of a Date object as in the getter method above.
If I print this object to the console, the date part is there but I get 00:00 for the minutes and hours part every time.
2018-04-10T00:00:00+05:30
How do I store Date + Time in a JDBC database and retrieve both?
The type of your field in your database is DATE so DATE only stores YYYY-MM-DD.
If you want to store also the time you must change the type of your field in your database to DATETIME. The representation of this is: YYYY-MM-DD HH:MI:SS
More information in: https://www.w3schools.com/sql/sql_datatypes.asp
tl;dr
You are using a date-only type to hold a date-time value – trying to fit a square peg into a round hole.
How do I store Date + Time in a JDBC database and retrieve both?
To store a moment, a date-time value, use a date-time type:
TIMESTAMP WITH TIME ZONE in your database.
Instant in Java.
You are using terribly confusing legacy classes. Use only java.time classes instead.
Databases vary
Databases vary widely in their date-time data types and their behavior. You do not specify your database, so we can only guess or abide by the SQL standard.
The SQL standard barely touches on the subject of date-time handling, unfortunately. The standard briefly defines:
DATE as a date-only value without time-of-day.
A TIMESTAMP WITHOUT TIME ZONE is a date and a time-of-day, but lacks any concept of time zone or offset-from-UTC, so it does not represent actual moments.
For actual moments, use TIMESTAMP WITH TIME ZONE. That type name can be misleading as some implementations such as Postgres do not store a zone with the value, but instead use any passed zone information to adjust into a UTC value for storage.
java.time
You are using terrible old date-time classes from the earliest versions of Java. Those were supplanted in Java 8 and later by the java.time classes. Never use Date or Calendar again.
Generally best to think, work, store, log, and exchange date-time values in UTC unless specifically required by the business logic or user-interface. So generally you should focus on the Instant class. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction). This class replaces java.util.Date.
Capture the current moment in UTC.
Instant instant = Instant.now() ; // Capture the current moment in UTC.
Store this Instant in a database column of SQL-standard type TIMESTAMP WITH TIME ZONE or whatever is akin to that in your particular database.
JDBC 4.2
As of JDBC 4.2 and later, you can directly exchange java.time objects with your database.
myPreparedStatement.setObject( … , instant ) ;
Retrieval.
Instant instant = myResultSet.getObject( … , Instant.class ) ;
Converting
If handed an obsolete XMLGregorianCalendar, immediately convert into java.time ZonedDateTime by way of the obsolete GregorianCalendar class.
ZonedDateTime zdt = myXmlGregCal.toGregorianCalendar().toZonedDateTime() ; // Convert from legacy classes to modern java.time class.
If you want to see that same moment in UTC rather than the wall-clock time used by the people of that particular region (time zone), extract an Instant.
Instant instant = zdt.toInstant() ; // Adjust from zoned moment to UTC. Same moment, same point on the timeline, different wall-clock time.
If you must inter-operate with old code not yet updated to java.time, you can convert back and forth. Tip: Try to stay within java.time as much as possible. The legacy classes are an awful mess of poor design.
java.util.Date myJavaUtilDate = java.util.Date.from( instant ) ;
And, going the other direction.
Instant instant = myJavaUtilDate.toInstant() ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
You are looking for a DATA_TYPE TIMESTAMP. You should change your Database if you can.

Date time in java from SQL

I have this piece of code
while(activecheck.next()){
Date status;
String vincheck;
Date curr = new Date();
int datecheck;
status = activecheck.getDate(8);
vincheck = activecheck.getString(2);
String update = "UPDATE Auctions SET status = '"+inactive+"' WHERE vin = '"+vincheck+"'";
datecheck = status.compareTo(curr);
if(datecheck < 0){
stmt6.executeUpdate(update);
}
}
Which iterates through a mysql table checking for inactive bids. I am trying to check whether the date and time listed in the sql row has been passed by the current time. However, whenever I do this, it seems to only be comparing the dates, and not the times. What could be the cause of this?
This is the format I am using : yyyy-MM-dd HH:mm:ss`
You should use type which is called Timestamp instead of the date. This way you will cover the date and the current time
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
tl;dr
if(
myResultSet.getObject( … , Instant.class ) // Retrieve `Instant` (a moment in UTC) from database using JDBC 4.2 or later.
.isBefore( Instant.now() ) // Comparing to the current moment captured in UTC.
)
{
…
}
java.util.Date versus java.sql.Date
You may be confusing this pair of unfortunately mis-named classes. The first is a date-with-time type, in UTC. The second is a date-only type. Actually the second pretends to be a date-only type but actually has a time-of-day set to 00:00:00. Even worse, the second inherits from the first, but the documentation instructs us to ignore that fact.
Confusing? Yes. These awful classes are very poorly designed. Avoid them.
java.time
You are using terribly troublesome old date-time classes that were supplanted years ago by the java.time classes.
Instant
The java.util.Date class is replaced by java.time.Instant. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
LocalDate
The java.sql.Date class is replaced by java.time.LocalDate. The LocalDate class represents a date-only value without time-of-day and without time zone.
JDBC 4.2
As of JDBC 4.2 and later, you can directly exchange java.time classes with your database. No need to ever use java.sql or java.util date-time types again.
Tip: Make a habit of always using a PreparedStatement to avoid SQL Injection risk. Not really any more work once you get used to it.
Instant instant = Instant.now() ; // Capture the current moment in UTC.
myPreparedStatement.setObject( … , instant ) ;
And retrieval.
Instant instant = myResultSet.getObject( … , Instant.class ) ;
Smart objects, not dumb strings
This is the format I am using : yyyy-MM-dd HH:mm:ss`
Date-time values stored in a database do not have a “format”. Those values are stored by some internally-defined mechanism that does not concern us. They are not strings (not in any serious database, that is).
Your database, and your Java date-time objects, can parse a string representing a date-time value to create that value. And they can generate a string to represent that value. But the string and the date-time value are distinct and separate, and should not be conflated.
Use java.time objects to exchange date-time values with your database, not mere strings, just as you would for numbers and other data types your database comprehends. Use strings only for communicating textual values.
Compare
To compare your retrieved values against the current moment, use the isBefore, isAfter, and equals methods of Instant class.
Instant now = Instant.now() ;
…
Instant instant = myResultSet.getObject( … , Instant.class ) ;
boolean isPast = instant.isBefore( now ) ;
if ( isPast ) {
…
}
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Creating Java Calendar, basic parameters

I would like to send a Java Calendar object over a web service (soap). I notice that this kind of object is too complex and there should be a better method to send the same information.
What are the basic attributes that should be sended over the web service, so the client can create a Java Calendar out of this attributes?
I'm guessing: TimeZone, Date, and Time?
Also, how can the client recreate the Calendar based on those attributes?
Thanks!
In fact I would go for Timezone tz (timezone the calendar was expressed in), Locale loc (used for data representation purpose) and long time (UTC time) if you want exactly the same object.
In most uses the time is enough though, the receiver will express it with his own timezone and locale.
I suppose the Calendar instance that you would like to send is of type java.util.GregorianCalendar. In that case, you could just use xsd:dateTime. For SOAP, Java will usually bind that to a javax.xml.datatype.XMLGregorianCalendar instance.
Translating between GregorianCalendarand XMLGregorianCalendar:
GregorianCalendar -> XMLGregorianCalendar: javax.xml.datatype.DatatypeFactory.newXMLGregorianCalendar(GregorianCalendar)
XMLGregorianCalendar -> GregorianCalendar: XMLGregorianCalendar.toGregorianCalendar()
The easiest way is to use a long value.
java.util.Calendar.getInstance().getTimeInMillis()
This returns the long value for the date. That value can be used to construct java.util.Date or a Calendar.
tl;dr
Use plain text, in UTC, in standard ISO 8601 format.
Instant.now().toString()
2018-01-23T01:23:45.123456Z
Instant.parse( "2018-01-23T01:23:45.123456Z" )
ISO 8601
The ISO 8601 standard is a well-designed practical set of textual formats for representing date-time values.
2018-01-14T03:57:05.744850Z
The java.time classes use these standard formats by default when parsing/generating strings. The ZonedDateTime class wisely extends the standard to append the name of a time zone in square brackets.
ZoneId z = ZoneId.of( "America/Los_Angeles" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;
String output = zdt.toString() ;
2018-01-13T19:56:26.318984-08:00[America/Los_Angeles]
java.time
The java.util.Calendar class is part of the troublesome old date-time classes bundled with the earliest versions of Java. These legacy classes are an awful mess, and should be avoided.
Now supplanted by the modern industry-leading java.time classes.
UTC
Generally best to communicate a moment using UTC rather than a particular time zone.
The standard format for a UTC moment is YYYY-MM-DDTHH:MM:SS.SSSSSSSSSZ where the T separates the year-month-day from the hour-minute-second. The Z on the end is short for Zulu and means UTC.
Instant
The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
Instant instant = Instant.now() ;
String output = instant.toString() ;
2018-01-14T03:57:05.744850Z
If a particular time zone is crucial, use a ZonedDateTime as shown above.
Parsing
These strings in standard format can be parsed to instantiate java.time objects.
Instant instant = Instant.parse( "2018-01-14T03:57:05.744850Z" ) ;
ZonedDateTime zdt = ZonedDateTime.parse( "2018-01-13T19:56:26.318984-08:00[America/Los_Angeles]" ) ;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time (JSR 310) classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Categories

Resources