myJavaUtilDate // The terrible `java.util.Date` class is now legacy. Use *java.time* instead.
.toInstant() // Convert this moment in UTC from the legacy class `Date` to the modern class `Instant`.
.atZone( ZoneId.of( "Africa/Tunis" ) ) // Adjust from UTC to the wall-clock time used by the people of a particular region (a time zone).
.toLocalDate() // Extract the date-only portion.
.atStartOfDay( ZoneId.of( "Africa/Tunis" ) ) // Determine the first moment of that date in that zone. The day does *not* always start at 00:00:00.
You are using terrible old date-time classes that were supplanted years ago by the modern java.time classes defined in JSR 310.
Date
? Instant
A java.util.Date
represent a moment in UTC. Its replacement is Instant
. Call the new conversion methods added to the old classes.
Instant instant = myJavaUtilDate.toInstant() ;
Specify the time zone in which you want your new time-of-day to make sense.
Specify a proper time zone name in the format of Continent/Region
, such as America/Montreal
, Africa/Casablanca
, or Pacific/Auckland
. Never use the 2-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( "America/Montreal" ) ;
ZonedDateTime
Apply the ZoneId
to the Instant
to get a ZonedDateTime
. Same moment, same point on the timeline, but different wall-clock time.
ZonedDateTime zdt = instant.atZone( z ) ;
You asked to change the time-of-day. Apply a LocalTime
to change all the time-of-day parts: hour, minute, second, fractional second. A new ZonedDateTime
is instantiated, with values based on the original. The java.time classes use this immutable objects pattern to provide thread-safety.
LocalTime lt = LocalTime.of( 15 , 30 ) ; // 3:30 PM.
ZonedDateTime zdtAtThreeThirty = zdt.with( lt ) ;
But you asked specifically for 00:00. So apparently you want the first moment of the day. Beware: some days in some zones do not start at 00:00:00. They may start at another time such as 01:00:00 because of anomalies such as Daylight Saving Time (DST).
Let java.time determine the first moment. Extract the date-only portion. Then pass the time zone to get first moment.
LocalDate ld = zdt.toLocalDate() ;
ZonedDateTime zdtFirstMomentOfDay = ld.atStartOfDay( z ) ;
If you need to go back to UTC, extract an Instant
.
Instant instant = zdtFirstMomentOfDay.toInstant() ;
Instant
? Date
If you need a java.util.Date
to interoperate with old code not yet updated to java.time, convert.
java.util.Date d = java.util.Date.from( instant ) ;