将java.util.Date转换为“java.time”类型? [英] Convert java.util.Date to what “java.time” type?

查看:173
本文介绍了将java.util.Date转换为“java.time”类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个



Instant h2>

java.time中的构建块是一个 Instant UTC时间轴上的一段时间,分辨率为纳秒秒



一般来说,你应该在UTC中做很多业务逻辑。在这样的工作中,将经常使用 Instant 。通过即时对象,仅应用时区以呈现给用户。当您需要应用偏移或时区时,请使用下面进一步介绍的类型。



java。 util.Date to Instant



鉴于 Instant java.util.Date 是时间轴上UTC的一小时,我们可以轻松地从 java.util.Date 即时。旧类获得了一种新的方法, java.util.Date::toInstant

 即时即时= myUtilDate。 toInstant(); 

您可以从另一个方向,从 Instant java.util.Date 。但是您可能会丢失关于第二分数的信息。 Instant 跟踪纳秒秒,小数点后最多九位数诸如 2016-01-23T12:34:56.123456789Z 的地方。 java.util.Date& .Calendar限于毫秒,小数位后最多三位数字,例如 2016- 01-23T12:34:56.123Z 。在这个例子中,从 Instant Date 意味着截断 456789

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



java.util.Calendar code>即时



java.util.Calendar 而不是一个 java.util.Date ?在日历对象的内部,日期时间被追踪为毫秒从1970年第一时间的UTC(<$ c $)的时代参考日期时间 c> 1970-01-01T00:00:00.0Z )。所以这个值可以很容易地转换成一个 Instant

 即时即时= myUtilCalendar.toInstant(); 



java.util.GregorianCalendar code> ZonedDateTime



更好的是,如果你的 java.util.Calendar 对象实际上是一个 java.util.GregorianCalendar ,您可以轻松地直接到 ZonedDateTime 。这种方法有利于保留嵌入式时区信息。



Downcast Calendar 的/en.wikipedia.org/wiki/Protocol_(object-oriented_programming)\"> interface concrete class GregorianCalendar 。然后调用 toZonedDateTime 方法来回。

  if(myUtilCalendar instanceof GregorianCalendar){
GregorianCalendar gregCal =(GregorianCalendar)myUtilCalendar; //从接口向具体类下载。
ZonedDateTime zdt = gregCal.toZonedDateTime(); //如果



,则在GregorianCalendar
中找到相同时区信息的ZonedDateTime p>向另一个方向...

  java.util.Calendar myUtilCalendar = java.util.GregorianCalendar.from(zdt); //产生一个实现`Calendar`接口的`GregorianCalendar`的瞬间。 

如上所述,请注意,您可能会丢失关于第二个。 java.time类型( ZonedDateTime )中的 nanoseconds 将被截断在 .Calendar / 毫秒 .GregorianCalendar



OffsetDateTime



Instant 我们可以应用从UTC偏移量进入某个地区的挂钟时间。偏移量是 UTC (向东)或UTC(向西)之后的几个小时,可能是几分钟和几秒钟。 。 ZoneOffset class代表这个想法。结果是 OffsetDateTime 对象。

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

您可以从另一个方向,从 OffsetDateTime java.util.Date 。提取 Instant ,然后按照我们上面的代码所示进行。如上所述,任何纳秒都被截断为数据丢失)。

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



ZonedDateTime



更好的是,应用一个完整的时区。时区是用于处理诸如夏令时(DST))之类异常的偏移量规则



应用 ZoneId 获得一个 ZonedDateTime 对象。使用正确的时区名称(大陆/地区)。不要使用常见的3-4个字母的缩写,如 EST IST ,因为它们既不标准化也不唯一。 / p>

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

您可以从另一个方向,从 ZonedDateTime java.util.Date 。提取 Instant ,然后按照我们上面的代码所示进行。如上所述,任何纳秒都被截断为数据丢失)。

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

我们进一步看到一个 ZonedDateTime 可以转换为 GregorianCalendar



LocalDate / h1>

有时候,您可能需要一个仅日期的值,没有时间,没有时区。为此,请使用 java.time.LocalDate 对象。



请参阅此问题以进行更多讨论,将java.util.Date转换为java.time.LocalDate ,特别是此答案,由背后是Joda-Time和java.time发明的主要人物。



关键是要经历一个 ZonedDateTime (如上面的代码生成的)。我们需要一个时区确定一个日期。日期在世界各地变化,东部早些时候开始了新的一天。例如,在巴黎的午夜之后,仍然是蒙特利尔的新一天。所以当一个 LocalDate 不包含时区时,需要一个时区确定 a LocalDate

  LocalDate localDate = zdt.toLocalDate(); 

将另一个方向从 LocalDate 转换为日期时间意味着发明一个时间。您可以选择在业务场景中有意义的任何时间。对于大多数人来说,这一天的第一个时刻是有道理的。时间 00:00:00.0 之前,您可能会尝试硬编码。在某些时区内,由于夏令时(DST)或其他异常情况,该时间可能无法第一时间生效。所以让java.time通过调用 atStartOfDay

  ZonedDateTime zdt = localDate.atStartOfDay(zoneId); 



LocalTime



在罕见的情况下,您可能只想要一个没有日期的时间,没有时区。此概念由 LocalTime 类。如上所述,使用 LocalDate ,我们需要一个时区来确定 LocalTime 即使 LocalTime 对象不包含(不记住)该时区。因此,我们再次看到如上所述从 Instant 获取的 ZonedDateTime 对象。

  LocalTime localTime = zdt.toLocalTime(); 



LocalDateTime



与其他两个 Local ... 类型一样,a LocalDateTime 没有指定时区和偏移量。因此您可能很少使用这个。它给你一个大概的日期时间,但是不是时间轴上的一个点。如果您的意思是一般的日期和一些可能应用于时区的时间,请使用此功能。



例如,今年圣诞节将是 2016-12-25T00:00:00.0 。请注意,在 LocalDateTime 的文本表示中缺少任何偏移或时区。圣诞节在德里印度比在巴黎法国早起,后来还在加拿大魁北克蒙特利尔。应用这些区域的每个时区将在时间轴上产生不同的时刻。

  LocalDateTime ldt = zdt.toLocalDateTime(); 


I have a java.util.Date object, or a java.util.Calendar object. How do I convert that to the right type in java.time framework?

I have heard that we should now be doing the bulk of our business logic with java.time types. When working with old code not yet updated for java.time I need to be able to convert back and forth. What types map to java.util.Date or java.util.Calendar?

解决方案

Yes, you definitely should be using the java.time framework whenever possible.

Avoid old date-time classes

The old date-time classes including java.util.Date, java.util.Calendar, and java.text.SimpleTextFormat and such have proven to be poorly designed, confusing, and troublesome. Avoid them where you can. But when you must interoperate with these old types, you can convert between old and new.

Read on for a basic introduction, somewhat over-simplified, to orient you in moving back-and-forth between the old and new date-time classes.

java.time

The java.time framework is defined by JSR 310, inspired by the highly-successful Joda-Time library, and extended by the ThreeTen-Extra project. The bulk of the functionality was back-ported to Java 6 & 7 in the ThreeTen-Backport project, with a further adaptation for Android in the ThreeTenABP project.

What java.time type matches java.util.Date? Well, a java.util.Date object basically represents a moment on the timeline in UTC, a combination of a date and a time-of-day. We can translate that to any of several types in java.time. Each is discussed below. Note that some new methods have been added to the old date-time classes to facilitate conversions.

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`
end if 

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();

这篇关于将java.util.Date转换为“java.time”类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆