tl;dr
myJavaUtilDate
.toInstant()
.atZone(
ZoneId.of( "Australia/Sydney" )
)
.toLocalDate()
For time-of-day only, without date and without time zone:
.toLocalTime()
To generate a string, call:
.format(
DateTimeFormatter
.ofLocalizedDate( FormatSyle.MEDIUM )
.withLocale( new Locale( "en" , "AU" ) )
)
Details
Immediately convert your java.util.Date
from its legacy class to the modern replacement, Instant
.
Instant instant = myJavaUtilDate.toInstant() ;
Both of those classes represent a moment as seen in UTC, that is, an offset of zero hours-minutes-seconds. Adjust into a time zone by which you want to perceive the date.
For any given moment the time-of-day and the date both vary by time zone around the globe. Noon in Paris is not noon in Montréal. And a new day dawns earlier in the east than in the west. You must get very clear on this to do proper date-time handling. One moment in nature can be viewed in many ways through human-created notions of time zones.
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 pseudo-zones such as AET
, EST
, or IST
as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "Australia/Sydney" ) ;
Apply to the Instant
to get a ZonedDateTime
. Both represent the same simultaneous moment, but are viewed with a different wall-clock time.
ZonedDateTime zdt = instant.atZone( z ) ;
Extract the date-only portion.
LocalDate ld = zdt.toLocalDate() ;
Extract the time-of-day portion.
LocalTime lt = zdt.toLocalTime() ;
Put them back together again.
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;
If you need a java.util.Date
again to interoperate with old code not yet updated to java.time, convert.
Date d = Date.from( zdt.toInstant() ) ;