我应该使用 java.util.Date 还是切换到 java.time.LocalDate
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28730136/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Should I use java.util.Date or switch to java.time.LocalDate
提问by Itai
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.? Are there any drawbacks to using this new API as opposed to the good old java.util.Date?
我正在编写一个不需要向后兼容的新项目。我应该只使用 LocalDate、LocalDateTime 等吗?与旧的 java.util.Date 相比,使用这个新 API 有什么缺点吗?
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?
特别是 - 我将主要使用 JDBC。从我所看到的 JDBC 处理 java.util.Date 很好。它也适用于 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.
谢谢。
回答by gerrytan
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
- The API includes addition/subtraction operation (minusMinutes, plusDays, etc)
- 更简单的格式/解析。API 有自己的格式/解析方法
- 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()));
回答by Ole V.V.
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-Backportfor 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.
如果您使用的是 Java 6 或 7,您将需要使用ThreeTen-Backport for java.time,进一步适用于ThreeTenABP中 API 级别 26 以下的 Android 。如果您只做很少非常简单的日期和时间工作并且向前兼容性不知何故不是问题,您可以考虑外部依赖是否值得。请考虑到您的外部依赖项只是 Java 8 及更高版本中内置内容的反向移植,因此非常可靠,因此您只会在迁移到 Java 8 或更高版本之前才需要它。届时您可以更改导入、重新测试并取消向后移植。
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. 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.
有一些例子,还有 JDK 中的库类。我的选择是在我自己的代码中使用 java.time 并且仅在调用尚未接受 java.time 类型的 API 之前进行转换。相反,如果我从 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 objectsand factory method, in contrast to most of the old classes.
我知道没有这样的模式。相反,与大多数旧类相比,java.time 使用模式不可变对象和工厂方法。
回答by Basil Bourque
I'm adding to the correct Answer by Ole V.V.
JDBC 4.2
JDBC 4.2
In particular - I am going to be working mainly with JDBC.
特别是 - 我将主要使用 JDBC。
JDBC 4.2added support for exchanging java.timeobjects with the database. See the PreparedStatement::setObject
and ResultSet::getObject
methods.
JDBC 4.2添加了对与数据库交换java.time对象的支持。见 PreparedStatement::setObject
和ResultSet::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 notrequire support for the two most commonly used classes: Instant
and ZonedDateTime
. Your database and JDBC drivermay or may not add support for these.
对于逃避我的原因,JDBC规范并没有要求对两种最常用的类支持:Instant
和ZonedDateTime
。您的数据库和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.
要通过特定地区(时区)的人们使用的挂钟时间查看这一时刻,请应用 aZoneId
来获取ZonedDateTime
对象。
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.
要调整为 UTC,请提取Instant
. 根据Instant
定义,An始终采用 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:at
,from
,to
,with
,等。
About java.time
关于java.time
The java.timeframework is built into Java 8 and later. These classes supplant the troublesome old legacydate-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
该java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如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.
要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310。
The Joda-Timeproject, now in maintenance mode, advises migration to the java.timeclasses.
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
You may exchange java.timeobjects directly with your database. Use a JDBC drivercompliant with JDBC 4.2or later. No need for strings, no need for java.sql.*
classes.
您可以直接与您的数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC 驱动程序。不需要字符串,不需要类。java.sql.*
Where to obtain the java.time classes?
从哪里获得 java.time 类?
- Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6and Java SE 7
- Most of the java.timefunctionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
- Later versions of Android bundle implementations of the java.timeclasses.
- For earlier Android (<26), the ThreeTenABPproject adapts ThreeTen-Backport(mentioned above). See How to use ThreeTenABP….
- Java SE 8、Java SE 9、Java SE 10、Java SE 11及更高版本 - 标准 Java API 的一部分,具有捆绑实现。
- Java 9 添加了一些小功能和修复。
- Java SE 6和Java SE 7
- 大部分java.time功能在ThreeTen-Backport中向后移植到 Java 6 & 7 。
- 安卓
- java.time类的更高版本的 Android 捆绑实现。
- 对于早期的 Android(<26),ThreeTenABP项目采用了ThreeTen-Backport(上面提到过)。请参阅如何使用ThreeTenABP ...。
The ThreeTen-Extraproject 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.
该ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如Interval
,YearWeek
,YearQuarter
,和更多。