簡體   English   中英

如何將時間單位從秒更改為天/月/年

[英]How to change time unit from seconds to days/months/years

我反對Java的Temporal API。 我在Java文檔或其他任何地方都找不到任何可以回答我需要做的事情。 我只需要以10億秒為單位返回一個日期並計算該日期,即某人活出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或其他任何地方找到方法,弄清楚如何使單位為年,月或日。

我需要做的就是返回一個Temporal對象,該對象聲明某人生活了十億秒的時刻。

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 [太平洋/奧克蘭]

細節

安德烈亞斯答案是正確的。 這里還有一些想法。

不要使用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 ) ;

看到此代碼在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() ; 

您可以調用plus(long amountToAdd, TemporalUnit unit) ,單位為ChronoUnit.SECONDS

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

輸出量

2031-09-09T01:46:40
2031-09-09T02:46:40-04:00[America/New_York]

因此,假設沒有夏令時,那么在2000年1月1日午夜出生的人將在2031年9月9日上午1:46:40達到10億秒的年齡。

如果他們住在紐約,那么就會是美國東部時間凌晨2:46:40。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM