如何将时间单位从秒更改为天/月/年

时间:2018-07-11 22:32:02

标签: java temporal

我正在反对Java的Temporal API。我在Java文档或其他任何地方都找不到任何可以回答我需要做的事情。我只需要以10亿秒的日期为日期并返回该日期,就可以计算某人生活十亿秒(大约30年左右)的时刻。

    public Temporal getGigasecondDate(Temporal given) {
        final long gigasecond = 1000000000;
        final long gigaDays = gigasecond / 60 / 60 / 24;

        Duration amount = Duration.ofDays(gigaDays);

        Temporal date = amount.addTo(given);

        return date;
    }

我收到一个错误消息,说Exception in thread "main" java.time.DateTimeException: Unit must be Years, Months or Days, but was Seconds,我一生无法在JavaDocs或其他任何地方找到方法,弄清楚如何将单位延长到数年,数月或数天。 / p>

我需要做的就是返回一个Temporal对象,该对象指出某人生活了十亿秒的时刻。

2 个答案:

答案 0 :(得分:4)

tl; dr

ZonedDateTime.of(                         // Mom gave birth at 3 AM in year 2000, New Zealand time.
    2000 , 1 , 23 , 3 , 45 , 0 , 0 , ZoneId.of( "Pacific/Auckland" )  
)                                         // Returns a `ZonedDateTime` object.
.plus(
    Duration.ofSeconds( 1_000_000_000L )  // A billion seconds.
)                                         // Returns another `ZonedDateTime` object. Immutable objects in *java.time* means we get a fresh object rather than “mutating” (altering) the original.
.toString()                               // Generate a `String` representing the value of our `ZonedDateTime` object, using standard ISO 8601 format wisely extended to append the name of the time zone in square brackets. 
  

2031-10-01T05:31:40 + 13:00 [太平洋/奥克兰]

详细信息

Answer by Andreas是正确的。这里还有一些想法。

请勿使用Temporal

java.time 的文档说明,通常在应用程序中,您应该使用具体的类,而不是接口和超类。在Temporal界面中引用:

  

此接口是框架级别的接口,不应在应用程序代码中广泛使用。相反,应用程序应创建并传递具体类型的实例,例如LocalDate。造成这种情况的原因很多,部分原因是该接口的实现可能在ISO以外的日历系统中。有关问题的更详细讨论,请参见ChronoLocalDate。

使出生时刻增加十亿秒

  

[将] 1,000,000,000秒添加到日期并返回日期,

确定该人的出生时刻。

LocalDate ld = LocalDate.of( 2000 , Month.JANUARY , 23 ) ;
LocalTime lt = LocalTime.of( 3 , 45 ) ;  // Mom gave birth at 3 AM in New Zealand time.
ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;

如果有用,请在UTC中查看同一时刻。

Instant instant = zdt.toInstant() ;

定义添加时间。 Duration类表示未附加到时间轴上的时间跨度。

Duration d = Duration.ofSeconds( 1_000_000_000L ) ;  

添加。

ZonedDateTime zdtLater = zdt.plus( d ) ;

或者,以UTC(相同的时刻,不同的挂钟时间)。

Instant instantLater = instant.plus( d ) ;

请参阅此code run live at IdeOne.com

  

zdt.toString():2000-01-23T03:45 + 13:00 [太平洋/奥克兰]

     

instant.toString():2000-01-22T14:45:00Z

     

d.toString():PT277777H46M40S

     

zdtLater.toString():2031-10-01T05:31:40 + 13:00 [太平洋/奥克兰]

     

instantLater.toString():2031-09-30T16:31:40Z

如果您只关心日期,没有时间和时区,请提取LocalDate

LocalDate ldLater = zdtLater.toLocalDate() ; 

答案 1 :(得分:1)

您可以呼叫plus(long amountToAdd, TemporalUnit unit),单位为ChronoUnit.SECONDS

<!DOCTYPE html>
<html>

<head>
    <title>FlyingSprite</title>
    <script src="FlyingSprite.js"></script>
</head>

<body>
    <div id="gameArea">
        <canvas id="myCanvas" width="800" height="480"></canvas>
    </div>
</body>

</html>

测试

public static Temporal getGigasecondDate(Temporal given) {
    return given.plus(1_000_000_000, ChronoUnit.SECONDS);
}

输出

System.out.println(getGigasecondDate(LocalDateTime.of(2000, 1, 1, 0, 0)));
System.out.println(getGigasecondDate(ZonedDateTime.of(2000, 1, 1, 0, 0, 0, 0, ZoneId.of("America/New_York"))));

因此,假设没有夏令时,那么2000年1月1日午夜出生的人将在2031年9月9日凌晨1:46:40达到10亿秒的年龄。

如果他们住在纽约,那就是美国东部时间凌晨2:46:40。