If your goal is to alter a date-time by setting a specific time-of-day…
tl;dr
ZonedDateTime.of(
LocalDate.now( ZoneId.of( "America/Chicago" ) ) , // Get the current date for a particular place on Earth.
LocalTime.parse( "15:00" ) , // Specify the time-of-day.
ZoneId.of( "America/Chicago" ) // Assign the intended zone to the resulting `ZonedDateTime` object.
)
Issue
You are parsing a String representing a time-of-day as a date-time value. That parsing method assumes you want the first day since the epoch reference date of 1970-01-01T00:00:00Z. So you got 3 PM on January 1st of 1970. That is all correct documented behavior. But not what you intended.
Solution
Avoid legacy classes
Avoid the troublesome old date-time classes bundled with the earliest versions of Java such as Calendar
. These were supplanted years ago in Java 8 and Java 9 by the java.time classes. For earlier Android, see the last bullets below.
Time zone
Specify your intended time zone. If omitted, the JVM’s current default time zone is implicitly applied. That default may change at any moment during runtime, and so is unreliable.
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 CST
or EST
or IST
as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Chicago" ) ;
A time zone is crucial in determining a date and time-of-day. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
ZonedDateTime zdtNow = ZonedDateTime.now( z ) ;
Time-of-day
For a time-of-day only value, without any date and without an time zone, use the LocalTime
class.
LocalTime lt = LocalTime.parse( "15:00" ) ;
Date-only + Time-of-Day
You want the same date but with another time-of-day. So extract the date-only portion, combine with the desired time-of-day while applying the intended time zone to get a new ZonedDateTime
object.
LocalDate ld = zdtNow.toLocalDate() ;
ZonedDateTime zdtTodayAtThreePm = ZonedDateTime.of( ld , lt , z ) ;
Tip: Generally best to do your logging, serializing, and data exchange in UTC rather than a particular time zone. For that use the Instant
class. You can extract a Instant
from a ZonedDateTime
.
Instant instant = zdtTodayAtThreePm.toInstant() ; // Always in UTC.
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?