Yours is a duplicate of many other Questions. So I'll be brief.
There are two ways to represent three kinds of date-time values:
- Store and exchange date-time values in UTC if actual moment has passed ( payment made, invoice received, court papers served, shipment arrived, etc.), or if in the future you know you want a specific moment on the timeline regardless if politicians redefine the time zone such as changing Daylight Saving Time (DST).  For Java, use Instantclass. In SQL useTIMESTAMP WITH TIME ZONE.
- Store and exchange date-time values without zone/offset for scheduling future events far enough out in the future that politicians may change the time zone rules (dental appointment next year, interview in two months, party announcement, etc.). Politicians around the world have shown a penchant for twiddling with our clocks, often with little warning, sometimes only several weeks advance notice. For Java, use LocalDateTimeclass. In SQL, useTIMESTAMP WITHOUT TIME ZONE. To present a schedule, generate transient data in Java usingZonedDateTimeclass, viaInstant::atZonemethod.
- Store and exchange date-time values without zone/offset for non-specific events, such as the start of Christmas or saying "all our factories in Delhi, Düsseldorf, & Detroit, will close for a half-day at noon on October 30th this year" where we mean noon at each of their respective local times rather than at a simultaneous moment. For Java, use LocalDateTimeclass. In SQL, useTIMESTAMP WITHOUT TIME ZONE.
As a programmer and sysadmins, learn to think in UTC and in 24-hour time. Forget about your own parochial time zone while on the job. Keep a second clock set to UTC in the office.
How do you know the user’s expected/desired time zone? Ultimately the only sure way is to ask her/him. 
When serializing to text, use standard ISO 8601 formats. 
Avoid the terrible old date-time classes such as java.util.Date and java.sql.Date, etc. These are now legacy, supplanted by the excellent industry-leading java.time classes.
An  Instant represents a moment on the timeline in UTC. 
Instant instant = Instant.ofEpochMilli( millis ) ;
For presentation to user, adjust the UTC into a time zone they expect/desire. Think of this like internationalization, where you store references to a key, then for presentation use the retrieved key to look up a localized text value. 
Never use 3-4 character pseudo-time zones. True time zones have a continent/region name such as Asia/Kolkata and Pacific/Auckland.
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
Note that databases vary widely in their handling of date-time. The SQL standard barely touches on the subject. Study the docs and conduct experiments to be sure you understand it's behavior. Ditto for your JDBC driver. Tip: Postgres has some of the best support for date-time types and functions. 
With JDBC 4.2 and later, exchange data with database via java.time objects, by calling:
- PreparedStatement::setObject
- ResultSet::getObject
Example code
myPStmt.setObject.( … , myInstant ) ;
…and…
Instant instant = myResultSet.getObject( … , Instant.class ) ;