我应该使用 java.util.Date 还是切换到 java.time.LocalDate

编辑: 好吧,显然这是太基于意见,所以让我试着更准确地重新措辞-

在不需要向后兼容性的 Java 代码中使用 LocalDate、 LocalTime 等是否有明确的警告或缺点,如果有,是什么?

我正在寻找像“当前 EE 库 X 和 Y 不能正确使用 LocalDate”或“这个非常有用的模式被 LocalTime 打破了”等等。


(请参阅原问题)

在 Java8中,引入了一个新的 time API,即 Java.time。LocalDate 等等,但 java.util。没有将日期标记为已否决。

我正在写一个新项目,它不需要向后兼容。我应该只使用 LocalDate、 LocalDateTime 等吗?与旧的 java.util 相比,使用这个新的 API 有什么缺点吗。约会?

特别是-我将主要与 JDBC 一起工作。从我看到的 JDBC 处理 java.util 的情况来看。约会愉快。它同样适合 LocalDate 吗?

通过搜索可以找到很多告诉我们如何从一种格式转换到另一种格式的站点,但是对于新代码是否应该使用旧的 API,没有明确的答案。

谢谢。

119888 次浏览

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:

  • Easier format/parsing. The API has its own format/parse methods
  • The API includes addition/subtraction operation (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()));

Java 8 and later: no worries

No, there is no reason why you shouldn’t want to use java.time, the modern Java date and time API if you’re on Java 8 or later (where it’s built in).

The only thing one may briefly consider, is the one you have already excluded.

I am writing a new project, which does not need to be backwards compatible.

And even for backward compatibility you can safely use java.time since conversion methods are built into the old classes from Java 8.

Java 6 and 7: weigh

If you’re on Java 6 or 7, you will need to use the ThreeTen-Backport for java.time, further adapted for Android below API level 26 in ThreeTenABP. If you’re doing only very little very simple date and time work and forward compatibility somehow isn’t an issue, you may consider whether the external dependency is worth it. Please take into account that your external dependency is but a backport of what is built into Java 8 and later, so rock solid, and therefore furthermore that you will only need it until you migrate to Java 8 or later. At which time you can change your imports, retest and do away with the backport.

Your examples of thinkable liabilities

Current EE libraries X and Y don't work correctly with LocalDate

There are some examples of that, also library classes in the JDK. My choice would be to use java.time in my own code and only convert just before calling into the API that doesn’t yet accept a java.time type. And conversely if I get an instance of an outdated class from the API, convert it first thing and use java.time for the rest.

This very useful pattern is broken with LocalTime

I know of no such pattern. On the contrary java.time uses patterns immutable objects and factory method, in contrast to most of the old classes.

I’m adding to the correct Answer by Ole V.V.

JDBC 4.2

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.

Table of date-time types in Java (both modern and legacy) and in standard SQL.


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.