LocalDate
can be ambiguous
The Answer by Andy Turner is correct and valuable. In addition, I want to point out the inherent ambiguity of LocalDate
.
The LocalDate
class represents a date-only value, without time-of-day, without time zone. For any given moment, the date varies around the globe by time zone. At a particular moment, it may be “tomorrow” in Tokyo Japan while simultaneously being “yesterday” in Toledo Ohio US. Two different dates in effect at the very same moment.
So while you may think of a date as containing 24 hours, defining a specific range of moments, it does not. You must place the date in the context of a time zone to be able to determine moments. (And, by the way, days are not always 24 hours long.)
LocalDate localDate = LocalDate.of( 2021 , Month.JANUARY , 24 ) ;
ZoneId zoneTokyo = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime startOfDayTokyo = localDate.atStartOfDay( zoneTokyo ) ; // Determine a specific moment.
startOfDayTokyo.toString(): 2021-01-24T00:00+09:00[Asia/Tokyo]
To see that same moment in UTC, extract an Instant
object.
Instant instant = startOfDayTokyo.toInstant() ;
Notice the date is 23rd rather than 24th.
instant.toString(): 2021-01-23T15:00:00Z
See that same moment through third wall-clock time, that of Toledo Ohio US in time zone America/New_York
.
ZonedDateTime zdtToledo = instant.atZone( ZoneId.of( "America/New_York" ) ) ;
Notice the date is 23rd rather than 24th.
zdtToledo.toString(): 2021-01-23T10:00-05:00[America/New_York]
See this code run live at IdeOne.com.
So when storing a LocalDate
, you may want to also store the time zone name as well. In a database table, that would mean two columns.
As an example, think of birthday. If it were crucial to know someone’s age to the very day, then a date-only value is not enough. With only a date, a person appearing to turn 18 years old in Tokyo Japan would still be 17 in Toledo Ohio US. As another example, consider a due date in a contract. If stated as only a date, a stakeholder in Japan will see a task as overdue while another stakeholder in Toledo sees the task as on-time.
In contrast, when you mean a moment, a specific point on the timeline, use Instant
(or OffsetDateTime
or ZonedDateTime
).
