You seem to be confusing the various date-time types.

ISO 8601
The string 2018-06-04T22:00:00.000Z
is in standard ISO 8601 format. The Z
on the end means UTC, and is pronounced Zulu.
The ISO 8601 formats are wisely designed. They are easy to parse by machine. And they are easy to read by humans across cultures. Their primary purpose is to communicate date-time values in a textual format. You should indeed be using strings in these formats for exchanging date-time values between systems.
Instant
Parse as an Instant
in the java.time classes.
Instant instant = Instant.parse( "2018-06-04T22:00:00.000Z" ) ;
LocalDate
The LocalDate
class represents a date-only value without time-of-day and without time zone or offset-from-UTC.
A time zone is crucial in determining a date. 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.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment during runtime(!), so your results may vary. Better to specify your desired/expected time zone explicitly as an argument. If critical, confirm the zone with your user.
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" ) ;
LocalDate today = LocalDate.now( z ) ;
If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the code becomes ambiguous to read in that we do not know for certain if you intended to use the default or if you, like so many programmers, were unaware of the issue.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
So you need to decide by what time zone you want to perceive the moment in UTC as a date and time-of-day.
The ISO 8601 format for a date-only value is YYYY-MM-DD.
String output = ld.toString() ; // Example: 2019-01-23
…and…
LocalDate ld = LocalDate.parse( "2019-01-23" ) ;
To generate such a string in JavaScript, see Format JavaScript Date to yyyy-mm-dd.
OffsetDateTime
If you want UTC
itself, convert from Instant
to OffsetDateTime
. Then extract the date alone.
OffsetDateTime odt = instant.atOffset( ZoneOffsetUTC ) ; // Convert to the more flexible `OffsetDateTime` class from `Instant` class.
LocalDate ld = odt.toLocalDate() ; // Extract a date-only value.
ZonedDateTime
If you want a particular time zone, apply a ZoneId
to get a ZonedDateTime
. Then extract the date alone.
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = instant.atZone( z ) ; // Adjust from UTC to a time zone.
LocalDate ld = zdt.toLocalDate() ; // Extract a date-only value, dropping the time-of-day and the time zone.
By the way, note that ZonedDateTime
class in its toString
method extends the ISO 8601 format by appending the name of the time zone in square brackets. A wise addition, but may not be handled properly by some other systems.
LocalDateTime
The LocalDateTime
class is the wrong type to be using for an input such as 2018-06-04T22:00:00.000Z
or 2019-04-02T20:16:24.999Z
. These string inputs represent a moment, a specific point on the timeline. The LocalDateTime
class purposely lacks any concept of time zone or offset, so it cannot represent a moment.
People frequently misunderstand the nature of LocalDateTime
. The “Local” means any locality or every locality, but not a particular locality. For a moment in a specific locality, use ZonedDateTime
.
For more info, see What's the difference between Instant and LocalDateTime?.
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
.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
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?
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.