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

Iro*_*uca 62 java datetime date java-8 java-time

尝试转换为时java.util.Date,我收到以下异常java.time.LocalDate.

java.time.DateTimeException: Unable to obtain ZonedDateTime from TemporalAccessor: 2014-08-19T05:28:16.768Z of type java.time.Instant
Run Code Online (Sandbox Code Playgroud)

代码如下:

public static Date getNearestQuarterStartDate(Date calculateFromDate){

    int[] quaterStartMonths={1,4,7,10};     
    Date startDate=null;

    ZonedDateTime d=ZonedDateTime.from(calculateFromDate.toInstant());
    int frmDateMonth=d.getMonth().getValue();
Run Code Online (Sandbox Code Playgroud)

我使用ZonedDateTime课程的方式有问题吗?

根据文档,这应该将java.util.Date对象转换为ZonedDateTime.上面的日期格式是标准日期?

我是否必须回到Joda时间?

如果有人可以提供一些建议,那就太好了.

JB *_*zet 88

要将a转换Instant为a ZonedDateTime,请ZonedDateTime提供方法ZonedDateTime.ofInstant(Instant, ZoneId).所以

因此,假设您想要一个ZonedDateTime默认时区,您的代码应该是

ZonedDateTime d = ZonedDateTime.ofInstant(calculateFromDate.toInstant(),
                                          ZoneId.systemDefault());
Run Code Online (Sandbox Code Playgroud)

  • 日期根本没有时区.自精确时刻(1970-01-01T00:00 UTC)以来,已经过了几个毫秒.没有"相同"的时区.如果希望ZonedDateTime位于UTC时区,则必须传递ZoneOffset.UTC. (5认同)
  • @DidierA。`Date` 类似于 `Instant`,它们都是 UNIX 时间戳。此外,通常的做法是说 UNIX 时间戳是 UTC 时区。 (2认同)

ass*_*ias 33

要从日期获取ZonedDateTime,您可以使用:

calculateFromDate.toInstant().atZone(ZoneId.systemDefault())
Run Code Online (Sandbox Code Playgroud)

toLocalDate如果需要LocalDate,则可以调用该方法.另请参见:将java.util.Date转换为java.time.LocalDate

  • ZonedDateTime.from()需要一个ZoneId,但Instant没有.因此,ZonedDateTime.from(instant)会抛出异常. (2认同)

Bas*_*que 9

通过assylias答案按JB Nizet答案都是正确的:

  1. 调用添加到遗留类中的新转换方法,java.util.Date::toInstant
  2. 调用Instant::atZone,传递 a ZoneId,产生 a ZonedDateTime

在此处输入图片说明

但是您的代码示例是针对宿舍的。为此,请继续阅读。

宿舍

无需自行处理宿舍。使用已经编写和测试过的类。

org.threeten.extra.YearQuarter

java.time类由扩展ThreeTen-EXTRA项目。在该库中提供的许多方便的类中,您会发现QuarterYearQuarter.

首先得到你的ZonedDateTime.

ZonedId z = ZoneID.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = myJavaUtilDate.toInstant().atZone( z ) ;
Run Code Online (Sandbox Code Playgroud)

确定该特定日期的年季度。

YearQuarter yq = YearQuarter.from( zdt ) ;
Run Code Online (Sandbox Code Playgroud)

接下来我们需要该季度的开始日期。

LocalDate quarterStart = yq.atDay( 1 ) ;
Run Code Online (Sandbox Code Playgroud)

虽然我不一定建议这样做,但您可以使用单行代码而不是实现方法。

LocalDate quarterStart =                    // Represent a date-only, without time-of-day and without time zone.
    YearQuarter                             // Represent a specific quarter using the ThreeTen-Extra class `org.threeten.extra.YearQuarter`. 
    .from(                                  // Given a moment, determine its year-quarter.
        myJavaUtilDate                      // Terrible legacy class `java.util.Date` represents a moment in UTC as a count of milliseconds since the epoch of 1970-01-01T00:00:00Z. Avoid using this class if at all possible.
        .toInstant()                        // New method on old class to convert from legacy to modern. `Instant` represents a moment in UTC as a count of nanoseconds since the epoch of 1970-01-01T00:00:00Z. 
        .atZone(                            // Adjust from UTC to the wall-clock time used by the people of a particular region (a time zone). Same moment, same point on the timeline, different wall-clock time.
            ZoneID.of( "Africa/Tunis" )     // Specify a time zone using proper `Continent/Region` format. Never use 2-4 letter pseudo-zone such as `PST` or `EST` or `IST`. 
        )                                   // Returns a `ZonedDateTime` object.
    )                                       // Returns a `YearQuarter` object.
    .atDay( 1 )                             // Returns a `LocalDate` object, the first day of the quarter. 
;
Run Code Online (Sandbox Code Playgroud)

顺便说一句,如果您可以java.util.Date完全淘汰您的使用,请这样做。这是一个可怕的类,以及它的兄弟姐妹,例如Calendar. Date当您与尚未更新为java.time 的旧代码交互时,仅在必须的地方使用。


关于java.time

java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date, Calendar, & SimpleDateFormat

要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310

现在处于维护模式Joda-Time项目建议迁移到java.time类。

您可以直接与您的数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC 驱动程序。不需要字符串,不需要类。java.sql.*

从哪里获得 java.time 类?

ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如IntervalYearWeekYearQuarter,和更多