将java.util.Date转换为什么“ java.time”类型?

罗勒·布尔克

我有一个java.util.Date对象,或一个java.util.Calendar对象。如何在java.time框架中将其转换为正确的类型

我听说我们现在应该使用java.time类型来做大部分业务逻辑。当使用尚未为java.time更新的旧代码时,我需要能够来回转换。什么类型映射到java.util.Datejava.util.Calendar

罗勒·布尔克

是的,您绝对应该尽可能使用java.time框架。

避免使用旧的日期时间类

老式的日期时间类(包括java.util.Datejava.util.Calendar和)java.text.SimpleTextFormat已被证明设计不良,混乱且麻烦尽可能避免它们。但是,当您必须与这些旧类型进行互操作时,可以在新旧之间进行转换。

请继续阅读,以获取基本的介绍(有些简化),以使您适应在新旧日期时间类之间来回移动。

java.time

java.time框架由定义JSR 310,由大获成功的启发乔达时库,并通过扩展ThreeTen-EXTRA项目。的功能的大部分被后移植到Java 6和7在ThreeTen-反向移植项目,在为Android进一步适配ThreeTenABP项目。

哪些java.time类型匹配java.util.Date好吧,一个java.util.Date对象基本上代表了UTC时间轴上的一个时刻,它是日期和时间的组合。我们可以将其转换为java.time中的几种类型中的任何一种。每个都在下面讨论。请注意,一些新方法已添加到旧的日期时间类中,以促进转换。

从java.util.Date/.Calendar通过ZonedDateTime(或OffsetDateTime)转换为三种<code> Local…</ code>类型的示意图

Instant

The building block in java.time is an Instant, a moment on the timeline in UTC with a resolution of nanoseconds.

Generally you should do much of your business logic in UTC. In such work, Instant will be used frequently. Pass around Instant objects, applying a time zone only for presentation to a user. When you do need to apply an offset or time zone, use the types covered further below.

From java.util.Date to Instant

Given that both Instant and java.util.Date are a moment on the timeline in UTC, we can easily move from a java.util.Date to an Instant. The old class has gained a new method, java.util.Date::toInstant.

Instant instant = myUtilDate.toInstant();

You can go the other direction, from an Instant to a java.util.Date. But you may lose information about the fractional second. An Instant tracks nanoseconds, for up to nine digits after the decimal place such as 2016-01-23T12:34:56.123456789Z. Both java.util.Date & .Calendar are limited to milliseconds, for up to three digits after the decimal place such as 2016-01-23T12:34:56.123Z. In this example going from Instant to Date means truncation of the 456789.

java.util.Date myUtilDate = java.util.Date.from(instant);

From java.util.Calendar to Instant

What about a java.util.Calendar instead of a java.util.Date? Internal to the Calendar object the date-time is tracked as a count of milliseconds from the epoch reference date-time of the first moment of 1970 in UTC (1970-01-01T00:00:00.0Z). So this value can be converted easily to an Instant.

Instant instant = myUtilCalendar.toInstant() ;

From java.util.GregorianCalendar to ZonedDateTime

Even better, if your java.util.Calendar object is actually a java.util.GregorianCalendar you can easily go directly to a ZonedDateTime. This approach has the benefit of retaining the embedded time zone information.

Downcast from the interface of Calendar to the concrete class of GregorianCalendar. Then call the toZonedDateTime and from methods to go back and forth.

if (myUtilCalendar instanceof GregorianCalendar) {
    GregorianCalendar gregCal = (GregorianCalendar) myUtilCalendar; // Downcasting from the interface to the concrete class.
    ZonedDateTime zdt = gregCal.toZonedDateTime();  // Create `ZonedDateTime` with same time zone info found in the `GregorianCalendar`
}

Going the other direction…

java.util.Calendar myUtilCalendar = java.util.GregorianCalendar.from(zdt); // Produces an instant of `GregorianCalendar` which implements `Calendar` interface.

As discussed above, beware that you may be losing information about the fraction of a second. The nanoseconds in the java.time type (ZonedDateTime) gets truncated to milliseconds in the .Calendar/.GregorianCalendar.

OffsetDateTime

From an Instant we can apply an offset-from-UTC to move into a wall-clock time for some locality. An offset is a number of hours, and possibly minutes and seconds, ahead of UTC (eastward) or behind UTC (westward). The ZoneOffset class represents this idea. The result is an OffsetDateTime object.

ZoneOffset offset = ZoneOffset.of("-04:00"); 
OffsetDateTime odt = OffsetDateTime.ofInstant(instant, zoneOffset);

You can go the other direction, from an OffsetDateTime to a java.util.Date. Extract an Instant and then proceed as we saw in code above. As discussed above, any nanoseconds get truncated to milliseconds (data loss).

java.util.Date myUtilDate = java.util.Date.from(odt.toInstant());

ZonedDateTime

Better yet, apply a full time zone. A time zone is an offset plus rules for handling anomalies such as Daylight Saving Time (DST).

Applying a ZoneId gets you a ZonedDateTime object. Use a proper time zone name (continent/region). Never use the 3-4 letter abbreviations commonly seen such as EST or IST as they are neither standardized nor unique.

ZoneId zoneId = ZoneId.of("America/Montreal");
ZonedDateTime zdt = ZonedDateTime.ofInstant(instant, zoneId);

You can go the other direction, from an ZonedDateTime to a java.util.Date. Extract an Instant and then proceed as we saw in code above. As discussed above, any nanoseconds get truncated to milliseconds (data loss).

java.util.Date myUtilDate = java.util.Date.from( zdt.toInstant() );

And we saw further above that a ZonedDateTime may be converted to a GregorianCalendar.

LocalDate

Sometimes you may want a date-only value, without time-of-day and without time zone. For that, use a java.time.LocalDate object.

See this Question for more discussion, Convert java.util.Date to java.time.LocalDate, especially this Answer written by the main man behind the invention of both Joda-Time and java.time.

The key is to go through a ZonedDateTime (as generated in code above). We need a time zone to determine a date. The date varies around the world, with a new day dawning earlier in the east. For example, after midnight in Paris is a new day while still “yesterday” in Montréal. So while a LocalDate does not contain a time zone, a time zone is required to determine a LocalDate.

LocalDate localDate = zdt.toLocalDate();

Converting in the other direction from LocalDate to a date-time means inventing a time-of-day. You can choose any time-of-day that makes sense in your business scenario. For most people, the first moment of the day makes sense. You may be tempted to hard code that first moment as the time 00:00:00.0. In some time zones, that time may not be valid as the first moment because of Daylight Saving Time (DST) or other anomalies. So let java.time determine the correct time with a call to atStartOfDay.

ZonedDateTime zdt = localDate.atStartOfDay(zoneId);

LocalTime

On rare occasion you may want only a time-of-day without a date and without a time zone. This concept is represented by the LocalTime class. As discussed above with LocalDate, we need a time zone to determine a LocalTime even though the LocalTime object does not contain (does not ‘remember’) that time zone. So, again, we go through a ZonedDateTime object obtained from an Instant as seen above.

LocalTime localTime = zdt.toLocalTime();

LocalDateTime

As with the other two Local… types, a LocalDateTime has no time zone nor offset assigned. As such you may rarely use this. It gives you a rough idea of a date-time but is not a point on the timeline. Use this if you mean some general date and some time that might be applied to a time zone.

For example, “Christmas starts this year” would be 2016-12-25T00:00:00.0. Note the lack of any offset or time zone in that textual representation of a LocalDateTime. Christmas starts sooner in Delhi India than it does in Paris France, and later still in Montréal Québec Canada. Applying each of those areas’ time zone would yield a different moment on the timeline.

LocalDateTime ldt = zdt.toLocalDateTime();

在此处输入图片说明


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?

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类常见问题

Java8将java.util.Date转换为java.time.ZonedDateTime

来自分类Dev

将java.sql.Date和java.util.Date转换为org.joda.time.LocalDate

来自分类Dev

ClassCastException:无法将java.util.Date强制转换为java.sql.Date

来自分类Dev

类型不匹配:无法从java.util.Date转换为java.sql.Date

来自分类Dev

如何将java.util.Date转换为Java8 java.time.YearMonth

来自分类Dev

如何将org.joda.time.LocalDateTime转换为java.Util.Calendar?

来自分类Dev

错误:无法将类型java.lang.String的属性值转换为属性dob的必需类型java.util.Date?

来自分类Dev

将LocalDate和LocalTime转换为java.util.date的最佳方法是什么?

来自分类Dev

无法将类型为java.util.Date的17/04/16 00:00转换为类java.sql.Date

来自分类Dev

使用ZoneId.systemDefault()将java.util.Date转换为java.time.LocalDateTime

来自分类Dev

无法将java.lang.Long类型的对象转换为java.util.Date类型

来自分类Dev

Firebase“无法将类型为java.util.HashMap的值转换为int”

来自分类Dev

将java.util.Date转换为java.sql.Date会截断时间部分

来自分类Dev

差异将java.util.Date和java.time.Instant之间古老的日期时,

来自分类Dev

将字符串转换为java.util.date

来自分类Dev

如何将java.util.date转换为java.sql.date?

来自分类Dev

无法将java.util.Date强制转换为java.sql.Date

来自分类Dev

在Java 8中将String转换为java.util.Date

来自分类Dev

将DStream [java.util.Date]转换为DStream [String]

来自分类Dev

将字符串转换为java.util.date

来自分类Dev

使用ZoneId.systemDefault()将java.util.Date转换为java.time.LocalDateTime

来自分类Dev

Firebase“无法将类型为java.util.HashMap的值转换为int”

来自分类Dev

SQLException:无法使用休眠将java.util.Date强制转换为java.sql.Time

来自分类Dev

Thymeleaf和SpringBoot-无法将类型[java.lang.String]的属性值转换为必需的类型[java.util.Date]作为prope

来自分类Dev

无法将 java.util.HashMap 类型的值转换为 String 但代码中没有 hashmap?

来自分类Dev

如何将 String 转换为 java.util.date 以使其可插入到类型为“DATE”的 mysql 数据库列中?

来自分类Dev

无法将 java.util.Date 类型的值转换为 String

来自分类Dev

将 ZonedDateTime 转换为 java.util.Date

来自分类Dev

为什么不能将 java.util.stream.IntStream 转换为 java.util.stream.Stream<?扩展 R>

Related 相关文章

  1. 1

    Java8将java.util.Date转换为java.time.ZonedDateTime

  2. 2

    将java.sql.Date和java.util.Date转换为org.joda.time.LocalDate

  3. 3

    ClassCastException:无法将java.util.Date强制转换为java.sql.Date

  4. 4

    类型不匹配:无法从java.util.Date转换为java.sql.Date

  5. 5

    如何将java.util.Date转换为Java8 java.time.YearMonth

  6. 6

    如何将org.joda.time.LocalDateTime转换为java.Util.Calendar?

  7. 7

    错误:无法将类型java.lang.String的属性值转换为属性dob的必需类型java.util.Date?

  8. 8

    将LocalDate和LocalTime转换为java.util.date的最佳方法是什么?

  9. 9

    无法将类型为java.util.Date的17/04/16 00:00转换为类java.sql.Date

  10. 10

    使用ZoneId.systemDefault()将java.util.Date转换为java.time.LocalDateTime

  11. 11

    无法将java.lang.Long类型的对象转换为java.util.Date类型

  12. 12

    Firebase“无法将类型为java.util.HashMap的值转换为int”

  13. 13

    将java.util.Date转换为java.sql.Date会截断时间部分

  14. 14

    差异将java.util.Date和java.time.Instant之间古老的日期时,

  15. 15

    将字符串转换为java.util.date

  16. 16

    如何将java.util.date转换为java.sql.date?

  17. 17

    无法将java.util.Date强制转换为java.sql.Date

  18. 18

    在Java 8中将String转换为java.util.Date

  19. 19

    将DStream [java.util.Date]转换为DStream [String]

  20. 20

    将字符串转换为java.util.date

  21. 21

    使用ZoneId.systemDefault()将java.util.Date转换为java.time.LocalDateTime

  22. 22

    Firebase“无法将类型为java.util.HashMap的值转换为int”

  23. 23

    SQLException:无法使用休眠将java.util.Date强制转换为java.sql.Time

  24. 24

    Thymeleaf和SpringBoot-无法将类型[java.lang.String]的属性值转换为必需的类型[java.util.Date]作为prope

  25. 25

    无法将 java.util.HashMap 类型的值转换为 String 但代码中没有 hashmap?

  26. 26

    如何将 String 转换为 java.util.date 以使其可插入到类型为“DATE”的 mysql 数据库列中?

  27. 27

    无法将 java.util.Date 类型的值转换为 String

  28. 28

    将 ZonedDateTime 转换为 java.util.Date

  29. 29

    为什么不能将 java.util.stream.IntStream 转换为 java.util.stream.Stream<?扩展 R>

热门标签

归档