[英]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,因为它具有更强大的功能:
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的正确答案
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::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 not require support for the two most commonly used classes: Instant
and ZonedDateTime
. 对于逃避我的原因,JDBC规范并不要求两个最常用的类支持:
Instant
和ZonedDateTime
。 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中使用的命名约定 :
at
, from
, to
, with
等。
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.Date
, Calendar
和SimpleDateFormat
。
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 . 您可以在这里找到一些有用的类,比如
Interval
, YearWeek
, YearQuarter
,和更多 。
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构建到旧类中的。
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.
此时您可以更改导入,重新测试并取消后退。
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.