I have postgresql time column with type TIMESTAMP WITH TIME ZONE having a sample value like 1970-01-01 00:00:00+05:30 I want to compare a value
with Date value like:
Date date = new Date(0L);
i.e. Tue Jan 19 13:55:24 IST 2016
So I used
Timestamp timeStampDate = new Timestamp(date.getTime());
The above code gives timeStampDate.getTime() as 0.
How to convert it in the above format so that it can be compared, Currently comparing is giving no results.
How to format this date.
I basically want to convert " Date is Thu Jan 01 05:30:00 IST 1970 " to this format : "1970-01-01 00:00:00+05:30"
java.time
If your database driver supports JDBC 4.2 or later, use Instant to get data from your database where stored in a TIMESTAMP WITH TIME ZONE column.
Instant instant = myResultSet.getObject( … , Instant.class ) ;
For an older JDBC driver, use java.sql.Timestamp to get data from your database by calling getTimestamp on your ResultSet. That Timestamp object is in UTC. Postgres stores your TIMESTAMP WITH TIME ZONE in UTC, by the way, and loses the original time zone or offset-from-UTC that came with the incoming data after using that data to adjust into UTC as part of the storage process.
You should convert your java.sql.Timestamp/.Date/.Time to java.time types as soon as possible. Then proceed with your business logic.
In a nutshell, java.time is… An Instant is a moment on the timeline in UTC. Apply a time zone (ZoneId) to get a ZonedDateTime.
Convert To java.time
So convert from Timestamp, get an Instant, apply a ZoneId.
java.sql.Timestamp ts = myResultSet.getTimestamp( 1 );
…
Instant instant = ts.toInstant();
Specify your desired/expected time zone. Apply to the Instant.
ZoneId zoneId = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
Comparison
Get the current moment, for use in comparison.
ZonedDateTime now = ZonedDateTime.now( zoneId );
Compare by calling the isEqual, isBefore, or isAfter methods.
Boolean beforeNow = zdt.isBefore( now );
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
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
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
java.sql.Date date = java.sql.Date.valueOf("1900-01-01");
//-2209017600000
System.out.println(date.getTime());
java.sql.Timestamp timestamp = new Timestamp(date.getTime());
System.out.println(timestamp);
if directly running in unit test, the result will be 1900-01-01 00:00:00.0
if running with debug in unit test, the result will be 1970-01-01 07:30:00.0
How does it output 1900-01-01 00:00:00.0? Where is it stored?
Why not output 1970-01-01 00:00:00.0 ? becase I saw the comment of Timestamp constructor says milliseconds since January 1, 1970, 00:00:00 GMT. A negative number is the number of milliseconds before January 1, 1970, 00:00:00 GMT.
tl;dr
Avoid the terrible old date-time classes. Use java.time. Poof, all the bizarre behavior you are seeing is gone, and your question is moot.
LocalDate // A class to represent a date-only value, without time-of-day, without time zone. Replaces `java.sql.Date` which only pretends to be date-only but actually has both a time-of-day and a time zone.
.parse( "1900-01-01" ) // Standard ISO 8601 formatted strings are parsed directly by the *java.time* classes.
.atStartOfDay( // Let java.time determine the first moment of a day.
ZoneId.of( "Pacific/Auckland" )
) // Returns a `ZonedDateTime` object.
.toString() // Generates a `String` with text in standard ISO 8601 format, wisely extended by appending the name of the time zone in square brackets.
1900-01-01T00:00+11:30[Pacific/Auckland]
You are torturing yourself with these Questions about the legacy date-time classes. Sun, Oracle, and the JCP community all gave up on those classes years ago when adopting JSR 310. I suggest you do the same.
Never use java.sql.Date
This class is part of the terrible old date-time classes that were supplanted years ago by java.time classes. This java.sql.Date in particular is especially badly designed. It extends java.util.Date while the documentation tells us to ignore the fact of that inheritance. As a subclass, it pretends to be a date-only value but actually has a time-of-day inherited from the other Date, which in turn is misnamed having both a date and a time-of-day. In addition, a time zone lurks deep within these classes, though inaccessible without any getter or setter method. Confusing? Yes, an awful mess. Never use java.sql.Date.
Instead, use java.time.LocalDate.
LocalDate ld = LocalDate.parse( "1900-01-01" ) ;
ld.toString(): 1900-01-01
Never use java.sql.Timestamp
As with java.sql.Date, the java.sql.Timestamp class was replaced years ago. Use java.time.Instant. If handed a Timestamp, immediately convert using the new conversion methods added to the old classes.
If you want the first moment of the day for a particular date, let LocalDate determine that. The first moment is not always 00:00:00, so never assume that. Specify the time zone of the region whose people use the particular wall-clock time you care about.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = ld.atStartOfDay( z ) ;
To see the same moment in UTC, extract a 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 = zdt.toInstant() ;
If you wanted the first moment of the day in UTC, use OffsetDateTime.
OffsetDateTime odt = ld.atOffset( ZoneOffset.UTC ) ;
Conversion
If you must interoperate with old code not yet updated to java.time classes, you can convert back-and-forth. Call new methods added to the old classes.
java.sql.Timestamp ts = Timestamp.from( instant ) ;
…and…
Instant instant = ts.toInstant() ;
Ditto for date.
java.sql.Date d = java.sql.Date.valueOf( ld ) ;
…and…
LocalDate ld = d.toLocalDate() ;
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.
I have a java application in which I would like the time in UTC. Currently, the code uses a mix of java.util.Date and java.sql.Timestamp. To get the time in UTC, the programmer before me used:
For Date:
Date.from(ZonedDateTime.now(ZoneOffset.UTC)).toInstant();
For Timestamp:
Timestamp.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant());
However I have run multiple tests myself with this code and both of these lines return the current date/time(in my current timezone). From everything I have read it appears that Date/Timestamp does not have a zoneOffset value, but I cannot find a concrete statement of this.
Is there anyway to keep the timeZone (UTC) within the Date or Timestamp objects, or do I need to do some refactoring and use the actual ZonedDateTime object throughout my application? Also will this ZonedDateTime object be compatible with the current Timestamp object for sql?
Example:
public static void main (String args[])
{
ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneOffset.UTC);
Timestamp timestamp = Timestamp.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant());
Date date = Date.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant());
System.out.println("ZonedDateTime: " + zonedDateTime);
System.out.println("Timestamp: " + timestamp);
System.out.println("Date: " + date);
}
Output:
ZonedDateTime: 2017-04-06T15:46:33.099Z
Timestamp: 2017-04-06 10:46:33.109
Date: Thu Apr 06 10:46:33 CDT 2017
tl;dr
Instant.now() // Capture the current moment in UTC with a resolution up to nanoseconds.
Use only java.time classes. Avoid the troublesome old legacy date-time classes added before Java 8.
Using java.time
The programmer before you was making use of the new modern java.time classes that now supplant the notoriously troublesome old legacy date-time classes such as Date, Calendar, Timestamp.
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). To get the current moment in UTC is utterly simple: Instant.now.
Instant instant = Instant.now();
Converting
You should stick to the java.time classes, and avoid the legacy classes. But if absolutely necessary such as interfacing with old code not yet updated for java.time, you may convert to/from java.time. Look to new methods on old classes. The legacy class java.util.Date equivalent is Instant.
java.util.Date d = java.util.Date.from( myInstant); // To legacy from modern.
Instant instant = myJavaUtilDate.toInstant(); // To modern from legacy.
JDBC
Avoid the legacy date-time classes. Use java.time classes instead.
Your JDBC 4.2 compliant driver may be able to directly address java.time types by calling PreparedStatement::setObject and ResultSet::getObject.
myPreparedStatement.setObject( … , instant ) ;
… and …
Instant instant = myResultSet.getObject( … , Instant.class ) ;
If not, fall back to using the java.sql types, but as briefly as possible. Use new conversion methods added to the old classes.
myPreparedStatement.setTimestamp( … , java.sql.Timestamp.from( instant ) ) ;
… and …
Instant instant = myResultSet.getTimestamp( … ).toInstant() ;
No need for ZonedDateTime
Notice that we had no need for your mentioned ZonedDateTime as you said you were only interested in UTC. The Instant objects are always in UTC. That means that original code you quoted:
Date.from(ZonedDateTime.now(ZoneOffset.UTC)).toInstant();
…could have simply been shortened to:
Date.from( Instant.now() ) ;
Note that java.util.Date is always in UTC as well. However, its toString unfortunately applies the JVM’ current default time zone implicitly while generating the String. This anti-feature creates no end of confusion as you can see by searching on Stack Overflow.
If you want to see your Instant object’s UTC value through the lens of a region’s wall-clock time, assign a time zone ZoneId to get a ZoneDateTime.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as CDT or EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Chicago" );
ZonedDateTime zdt = instant.atZone( z );
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
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.
In Java, Date represents a point in time. It's not related to timestamp. When you call toString() method of a Date object, it converts that time to Platform's default Timestamp, e.g. Following will print date/time in UTC (as it sets default timezone to UTC):
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneOffset.UTC);
Timestamp timestamp = Timestamp.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant());
Date date = Date.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant());
System.out.println("ZonedDateTime: " + zonedDateTime);
System.out.println("Timestamp: " + timestamp);
System.out.println("Date: " + date);
I am trying to save a java.util.Date from an application to my SQL Server database using JDBC.
When I convert the java.util.Date to a java.sql.Date using the method below, it truncates the time part.
java.sql.Date javaSqlExpiryDate = new java.sql.Date(javaUtilExpiryDate.getTime());
System.out.println("javaUtilExpiryDate: " + javaUtilExpiryDate.toString());
System.out.println("javaSqlExpiryDate: " + javaSqlExpiryDate.toString());
The Console window reports the output as:
javaUtilExpiryDate: Thu Sep 01 18:19:08 IST 2016
javaSqlExpiryDate: 2016-09-01
How do I get it to retain the time part as well?
Yes, that's the expected and documented behavior.
Quote from the JavaDocs
To conform with the definition of SQL DATE, the millisecond values wrapped by a java.sql.Date instance must be 'normalized' by setting the hours, minutes, seconds, and milliseconds to zero in the particular time zone with which the instance is associated.
If you want to keep the time, you need to use java.sql.Timestamp (especially if the column in the database is defined as datetime).
Just change your import from java.sql.Date TO java.sql.Timestamp
tl;dr
myPreparedObject.setObject(
1 ,
myJavaUtilDate.toInstant() // Convert legacy object to modern java.time object, `Instant`.
)
Details
The other Answers are correct. The java.util.Date class represents a date and a time-of-day in UTC. The java.sql.Date represents only a date, without the time-of-day. Well, actually, the java.sql.Date pretends to represent only a date but actually, as a badly-designed hack, subclasses the java.util.Date class and therefore does have a time-of-day. Confusing? Yes. One of many reasons to avoid these awful old legacy classes.
Now we have a better way, the java.time classes.
java.time
In the old days you would convert your java.util.Date object to a java.sql.Timestamp.
Now, with a JDBC driver supporting JDBC 4.2 and later, you can send your java.time objects directly to/from the database. No need for either the java.util nor java.sql classes, just stick with java.time classes.
If you have to interface with old code using java.util.Date, convert to java.time.Instant using new methods added to the old classes.
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 = myJavaUtilDate.toInstant() ;
Exchange an Instant with the database via PreparedStatement::setObject and ResultSet::getObject.
myPreparedStatement.setObject( … , instant ) ;
And…
Instant instant = myResultSet.getObject( … , Instant.class ) ;
To see this moment through some other time zone than UTC, apply a ZoneId to get a ZonedDateTime.
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
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
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
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.
I have a jCalendar which method jCalendar.getDate() returns a date in the following form:
Mon Apr 06 11:10:00 PDT 2015
But I want it in the format yyyy-MM-dd to insert into a MySQL database
I tried the following code but it throws a ParseException
Date fecha = jFecha.getDate(); //this returns Mon Apr 06 11:10:00 PDT 2015
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
fecha = format.parse(fecha.toString());
This code returns a Unparseable date: "Mon Apr 06 11:10:00 PDT 2015" error. I've tried setting the dateFormatString property of the jCalendar to yyyy-MM-dd but it still returns the same full date with seconds and everything.
Any idea of what I'm doing wrong?
First of all, a Date object does not have a format by itself. You cannot have "a Date object in the format yyyy-MM-dd" - there's no such thing as a Date object in a certain format.
How are you inserting the Date in the database - are you using JDBC? If yes, then use a PreparedStatement and pass a java.sql.Date object as the parameter. Like this:
PreparedStatement ps = connection.prepareStatement(
"insert into mytable (name, date) values (?, ?)");
ps.setParameter(1, "somename");
ps.setParameter(2, new java.sql.Date(fecha.getTime()));
ps.executeUpdate();
tl;dr
I want it in the format yyyy-MM-dd to insert into a MySQL database
No need to generate or parse a String. With a Date object in hand, convert to a java.time.Instant, apply a time zone ZoneId to generate a ZonedDateTime, and extract a LocalDate. Pass the LocalDate via JDBC 4.2 and later.
myPreparedStatement.setObject(
… ,
myJavaUtilDate.toInstant()
.atZone( ZoneId.of( "Pacific/Auckland" ) )
.toLocalDate() ,
LocalDate.class
)
Details
jCalendar.getDate() returns a date in the following form: Mon Apr 06 11:10:00 PDT 2015
The old Date & Calendar classes have many flaws. One of the flaws is the poor design decision to have the Date::toString method apply a time zone during the process of generating the string. This creates the illusion of an assigned time zone when actually the Date value is always in UTC.
Avoid the troublesome old date-time classes. They are now legacy, supplanted by the java.time classes.
Convert that Date to an 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 = myUtilDate.toInstant() ;
For a date-only value, you must decide on time zone. For example, a few minutes after midnight in Paris France is a new day while in Montréal Québec is still “yesterday”. So you must specify the context of a zone to determine the intended date.
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
For a date-only value, without time-of-day and without time zone, extract a LocalDate.
LocalDate ld = zdt.toLocalDate() ;
To exchange date-time values with a database, use date-time objects rather than mere strings. No need for you to generate or parse that problematic string.
If your JDBC driver complies with JDBC 4.2 and later, you can directly use the java.time types rather than the legacy java.sql types.
myPreparedStatement.setObject ( 1 , ld ); // Automatic detection and conversion of data type.
…and…
LocalDate ld = myResultSet.getObject ( "my_date_column_" , LocalDate.class );
For more discussion, see Insert & fetch java.time.LocalDate objects to/from an SQL database such as H2.
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, 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.
Do this instead:
Date fecha = jFecha.getDate(); //this returns Mon Apr 06 11:10:00 PDT 2015
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
fecha = format.format(fecha);
Actually you are supposed to use format instead of parse
I have a Joda DateTime object representing a UTC time, and wish to store it in a Timestamp field in a MySql table.
I have the following code:
String ztime = "2013-10-07T08:00:00Z";
DateTimeFormatter parser = ISODateTimeFormat.dateTimeParser();
DateTime dt = parser.parseDateTime(ztime).withZone(DateTimeZone.UTC);
PreparedStatement stmt = con.prepareStatement("insert into time_test (time) values (?)");
stmt.setTimestamp(1, Timestamp(dt.getMillis()));
stmt.execute();
However, when I look in the database, the time that gets store is out by the difference of my database's timezone from UTC.
e.g. when my database is running in UTC+1, and run the above code to save "08:00Z", in the database the Timestamp shows as 09:00.
DateTime's getMillis method says " Gets the milliseconds of the datetime instant from the Java epoch of 1970-01-01T00:00:00Z."
and MySql's Timestamp says: "MySQL converts TIMESTAMP values from the current time zone to UTC for storage, and back from UTC to the current time zone for retrieval.",
so I presume it's the MySql conversion that's causing the issue, because the millis it's being initialized with is relative to a fixed UTC time, so it has no need to convert from current time zone to UTC.
My code to read the data back out into a DateTime works fine, and I get the value out that I put in, but I also need this to work with some 3rd-party code over which
I have no control, which expects the Timestamp to be in the correct UTC time.
How do I get the Timestamp field in the database to match my original UTC date/time ?
tl;dr
Use java.time classes that supplant Joda-Time.
myPreparedStatement.setObject(
… ,
Instant.parse( "2013-10-07T08:00:00Z" )
)
Retrieve.
myResultSet.getObject(
… ,
Instant.class
)
java.time
The Joda-Time project is now in maintenance-mode, recommending migration to its successor, the java.time classes built into Java 8 and later. Both are led by the same man, Stephen Colebourne. You'll find many of the same concepts in play, so fairly easy to migrate.
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).
Your input string happens to be in standard ISO 8601 format. The java.time classes use these standard formats by default when parsing/generating strings. So no need to specify a formatting pattern.
String input = "2013-10-07T08:00:00Z" ; // Standard ISO 8601 format.
Instant instant = Instant.parse( input ) ; // Parses standard ISO 8601 format by default.
The Instant class replaces both java.util.Date and java.sql.Timestamp. As of JDBC 4.2 and later, you can directly exchange java.time objects with the database.
myPreparedStatement.setObject( … , instant ) ;
And retrieval.
Instant instant = myResultSet.getObject( … , Instant.class ) ;
The TIMESTAMP type in MySQL seems to be akin to the SQL-standard TIMESTAMP WITH TIME ZONE type. So the code above should work appropriately.
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.