Edit: Well, apparently it was too opinion based, so let me try to reword it more precisely -
Are there any clear caveats or drawbacks of using LocalDate, LocalTime etc. in a Java code that does not need any backwards compatibility, and if so - what are they?
I'm looking for things like "Current EE libraries X and Y don't work correctly with LocalDate" or "This very useful pattern is broken with LocalTime" et cetera.
(here is the original question for reference)
With Java 8, a new time API is introduced, namely the java.time.LocalDate etc., but java.util.Date is not marked as deprecated.
I am writing a new project, which does not need to be backwards compatible. Should I only use LocalDate, LocalDateTime etc.? Are there any drawbacks to using this new API as opposed to the good old java.util.Date?
In particular - I am going to be working mainly with JDBC. From what I have seen JDBC handles java.util.Date well. Is it as well suited for LocalDate?
Searching yielded lots of sites telling how to convert from one format to the other, but no definitive answer as to should new code use the old API.
Thanks.
Some other problems are: It rates years as two digits since 1900. There are many workarounds in the Java world around this banal design decision, like handling years before 1900. Months are zero indexed (0 – January, 11 – December).
Date class and how that can be converted to a LocalDate as well. Starting with Java 8, we can find an additional toLocalDate() method on java. sql. Date, which also gives us an easy way of converting it to java.
For example, the old Date class contains both date and time components but LocalDate is just date, it doesn't have any time part in it like "15-12-2016", which means when you convert Date to LocalDate then time-related information will be lost and when you convert LocalDate to Date, they will be zero.
Despite the name, java.util.Date
can be used to store both date and time (it stores UTC milliseconds offset since epoch)
I would definitely use the new API because of greater features:
minusMinutes
, plusDays
, etc)None of above are available on java.util.Date
Old Date can also be converted into LocalDateTime
like this:
Date oldDate = ... LocalDateTime newDateTime = LocalDateTime.from(Instant.ofEpochMilli(oldDate.getTime()));
I’m adding to the correct Answer by Ole V.V.
In particular - I am going to be working mainly with JDBC.
JDBC 4.2 added support for exchanging java.time objects with the database. See the PreparedStatement::setObject
and ResultSet::getObject
methods.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ; LocalDate today = LocalDate.now( z ) ; myPreparedStatement.setObject( … , today ) ;
Retrieval.
LocalDate ld = myResultSet.getObject( … , LocalDate.class ) ;
For reasons that escape me, the JDBC spec does not require support for the two most commonly used classes: Instant
and ZonedDateTime
. Your database and JDBC driver may or may not add support for these.
If not, you can easily convert. Start with OffsetDateTime
, with support required in JDBC.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
To see this moment through the wall-clock time used by people of a particular region (a time zone), apply a ZoneId
to get a ZonedDateTime
object.
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ; ZonedDateTime zdt = odt.atZoneSameInstant() ;
To adjust into UTC, extract an Instant
. An Instant
is always in UTC, by definition.
Instant instant = odt.toInstant() ;
You can convert the other way, to write to a database.
myPreparedStatement.setObject( … , zdt.toOffsetDateTime() ; // Converting from `ZonedDateTime` to `OffsetDateTime`. Same moment, same point on the timeline, different wall-clock time.
…and:
myPreparedStatement.setObject( … , instant.atOffset( ZoneOffset.UTC ) ) ; // Converting from `Instant` to `OffsetDateTime`. Same moment, same point on the timeline, and even the same offset. `OffsetDateTime` is a more flexible class with abilities such as (a) applying various offsets and (b) flexible formatting when generating text, while `Instant` is meant to be a more basic building-block class.
Notice the naming convention used in java.time: at
, from
, to
, with
, and so on.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With