简体   繁体   English

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

[英]Should I use java.util.Date or switch to java.time.LocalDate

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? 在不需要任何向后兼容性的Java代码中使用LocalDate,LocalTime等有任何明确的警告或缺点,如果是这样 - 它们是什么?

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. 我正在寻找像“当前EE库X和Y无法正确使用LocalDate”或“这个非常有用的模式被LocalTime打破”等等。


(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. 在Java 8中,引入了新的时间API,即java.time.LocalDate等,但java.util.Date未标记为已弃用。

I am writing a new project, which does not need to be backwards compatible. 我正在编写一个新项目,它不需要向后兼容。 Should I only use LocalDate, LocalDateTime etc.? 我应该只使用LocalDate,LocalDateTime等吗? Are there any drawbacks to using this new API as opposed to the good old java.util.Date? 使用这个新API是否有任何缺点,而不是旧的java.util.Date?

In particular - I am going to be working mainly with JDBC. 特别是 - 我将主要使用JDBC。 From what I have seen JDBC handles java.util.Date well. 从我所看到的JDBC很好地处理java.util.Date。 Is it as well suited for LocalDate? 它是否适合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. 搜索产生了许多网站,告诉他们如何从一种格式转换为另一种格式,但是如果新代码使用旧的API,则没有明确的答案。

Thanks. 谢谢。

Despite the name, java.util.Date can be used to store both date and time (it stores UTC milliseconds offset since epoch) 尽管名称,java.util.Date可用于存储日期和时间(它存储自纪元以来的UTC毫秒偏移量)

I would definitely use the new API because of greater features: 我肯定会使用新的API,因为它具有更强大的功能:

  • Easier format/parsing. 更容易格式化/解析。 The API has its own format/parse methods API有自己的格式/解析方法
  • The API includes addition/subtraction operation (minusMinutes, plusDays, etc) API包括加法/减法操作(minusMinutes,plusDays等)

None of above are available on java.util.Date 以上都不适用于java.util.Date

Old Date can also be converted into LocalDateTime like this: Old Date也可以像这样转换为LocalDateTime:

Date oldDate = ...
LocalDateTime newDateTime = 
  LocalDateTime.from(Instant.ofEpochMilli(oldDate.getTime()));

I'm adding to the correct Answer by Ole VV 我正在添加Ole VV正确答案

JDBC 4.2 JDBC 4.2

In particular - I am going to be working mainly with JDBC. 特别是 - 我将主要使用JDBC。

JDBC 4.2 added support for exchanging java.time objects with the database. JDBC 4.2增加了对与数据库交换java.time对象的支持。 See the PreparedStatement::setObject and ResultSet::getObject methods. 请参阅PreparedStatement::setObjectResultSet::getObject方法。

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 . 对于逃避我的原因,JDBC规范并不要求两个最常用的类支持: InstantZonedDateTime Your database and JDBC driver may or may not add support for these. 您的数据库和JDBC驱动程序可能会也可能不会添加对这些的支持。

If not, you can easily convert. 如果没有,您可以轻松转换。 Start with OffsetDateTime , with support required in JDBC. OffsetDateTime开始,需要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以获取ZonedDateTime对象。

ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant() ;

To adjust into UTC, extract an Instant . 要调整为UTC,请提取Instant An Instant is always in UTC, by definition. 根据定义, Instant始终为UTC。

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. 请注意java.time中使用命名约定atfromtowith等。

Java(现代和旧版)和标准SQL中的日期时间类型表。


About java.time 关于java.time

The java.time framework is built into Java 8 and later. java.time框架内置于Java 8及更高版本中。 These classes supplant the troublesome old legacy date-time classes such as java.util.Date , Calendar , & SimpleDateFormat . 这些类取代了麻烦的旧遗留日期时间类,如java.util.DateCalendarSimpleDateFormat

To learn more, see the Oracle Tutorial . 要了解更多信息,请参阅Oracle教程 And search Stack Overflow for many examples and explanations. 并搜索Stack Overflow以获取许多示例和解释。 Specification is JSR 310 . 规范是JSR 310

The Joda-Time project, now in maintenance mode , advises migration to the java.time classes. 现在处于维护模式Joda-Time项目建议迁移到java.time类。

You may exchange java.time objects directly with your database. 您可以直接与数据库交换java.time对象。 Use a JDBC driver compliant with JDBC 4.2 or later. 使用符合JDBC 4.2或更高版本的JDBC驱动程序 No need for strings, no need for java.sql.* classes. 不需要字符串,不需要java.sql.*类。

Where to obtain the java.time classes? 从哪里获取java.time类?

The ThreeTen-Extra project extends java.time with additional classes. ThreeTen-Extra项目使用其他类扩展了java.time。 This project is a proving ground for possible future additions to java.time. 该项目是未来可能添加到java.time的试验场。 You may find some useful classes here such as Interval , YearWeek , YearQuarter , and more . 您可以在这里找到一些有用的类,比如IntervalYearWeekYearQuarter ,和更多

Java 8 and later: no worries Java 8及更高版本:无后顾之忧

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). 不,如果您使用的是Java 8或更高版本(内置它),那么您就不应该使用java.time这个现代Java日期和时间API。

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.time,因为转换方法是从Java 8构建到旧类中的。

Java 6 and 7: weigh Java 6和7:权衡

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 . 如果您使用的是Java 6或7,则需要使用适用于java.time的ThreeTen- Backport,进一步适用于ThreeTenABP中API级别26以下的Android。 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. 请注意,您的外部依赖项只是Java 8及更高版本中内置的后端,因此非常坚固,因此在迁移到Java 8或更高版本之前,您只需要它。 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 当前EE库X和Y无法与LocalDate一起正常工作

There are some examples of that, also library classes in the JDK. 这里有一些例子,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. 我的选择是在我自己的代码中使用java.time,只在调用之前转换为尚未接受java.time类型的API。 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. 相反,如果我从API获得一个过时类的实例,首先将其转换为其余部分并使用java.time。

This very useful pattern is broken with LocalTime 使用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. 相反,java.time使用模式不可变对象工厂方法 ,与大多数旧类相反。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM