亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Java當前日期和過去日期之間的年,月,日,小時,分鐘,秒之間的差異

Java當前日期和過去日期之間的年,月,日,小時,分鐘,秒之間的差異

白衣染霜花 2022-10-20 15:14:46
我知道這已經在這里被問過很多次了,但我一直無法找到任何特定于我的案例的東西。我試圖找出當前日期時間和以前的日期時間之間的區別,每個日期時間的格式都是yyyy-MM-dd HH:mm:ss.s. 根據此處給出的答案,我提出了以下代碼:SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.s");String earliestRunTime = "2017-12-16 01:30:08.0";Date currentDate = new Date();log.info("Current Date: {}", format.format(currentDate));try {    Date earliestDate = format.parse(earliestRunTime);    long diff = currentDate.getTime() - earliestDate.getTime();    long diffSeconds = diff / 1000 % 60;    long diffMinutes = diff / (60 * 1000) % 60;    long diffHours = diff / (60 * 60 * 1000) % 24;    long diffDays = diff / (24 * 60 * 60 * 1000) % 30;    long diffMonths = diff / (30 * 24 * 60 * 60 * 1000) % 12;    long diffYears = diff / (12 * 30 * 24 * 60 * 60 * 1000);    return String.format("%s years, %s months, %s days, %s hours, %s minutes, %s seconds",            diffYears, diffMonths, diffDays, diffHours, diffMinutes, diffSeconds);    }catch (Exception e) {    e.printStackTrace();    return e.getMessage();}當我運行代碼時,JSON 返回以下結果:lifetime: "41 years, -1 months, 14 days, 9 hours, 42 minutes, 37 seconds"我在這里有兩個問題:我在 41 年和負數的計算中哪里出錯了?我有更好的方法嗎?我當前的設置不考慮閏年或 365 天一年,我需要將這些考慮在內。
查看完整描述

3 回答

?
阿波羅的戰車

TA貢獻1862條經驗 獲得超6個贊

  1. 我在 41 年和負數的計算中哪里出錯了?

除了使用臭名昭著的麻煩和過時SimpleDateFormat的類以及同樣過時的類之外Date,您的代碼中還有以下錯誤:

  • 您正在解析08.0為 8 秒 0 秒。在我的 JDK-11 上SimpleDateFormat選擇 0 秒并丟棄我認為正確的 8 秒。SimpleDateFormat無法解析秒上的一位小數(僅精確三位小數),因此該錯誤的解決方案是完全丟棄SimpleDateFormat。

  • 正如其他人所說int,您的乘法溢出。例如,30 * 24 * 60 * 60 * 1000應該給出 2 592 000 000,但由于 anint不能保存這個數字,所以你得到-1 702 967 296了。因為這是一個負數,所以下面的除法給你一個負數的月數。

  • 正如 Solomon Slow 在評論中指出的那樣,一個月可能是 28、29、30 或 31 天。將所有月份設置為 30 天時,您將面臨不正確的天數和月份數以及最終年份數的風險。當我今天運行你的代碼時,正確的答案是 1 年 4 個月 13 天,但我得到了 19 天,6 天太多了。

  • 您沒有考慮夏令時 (DST) 和其他時間異常。這些可能會導致一天為例如 23 或 25 小時,從而產生錯誤。

或者總結一下:您的錯誤是您試圖“手動”進行計算。日期和時間數學太復雜且容易出錯,無法執行此操作。您應該始終將其留給經過充分驗證的庫類。

  1. 我有更好的方法嗎?我當前的設置不考慮閏年或 365 天一年,我需要將這些考慮在內。

是的,有一個更好的方法。最好的方法可能是使用PeriodDurationThreeTen Extra 項目中的類,請參見下面的鏈接。我現在不打算在我的計算機上安裝那個庫,所以我將只展示使用內置類的好的和現代的解決方案:

    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss.S");

    LocalDateTime currentDateTime = LocalDateTime.now(ZoneId.of("Australia/Sydney"));

    String earliestRunTime = "2017-12-16 01:30:08.0";

    LocalDateTime earliestDateTime = LocalDateTime.parse(earliestRunTime, dtf);


    // We want to find a period (years, months, days) and a duration (hours, minutes, seconds).

    // To do that we cut at the greatest possible whole number of days

    // and then measure the period before the cut and the duration after it.

    LocalDateTime cut = earliestDateTime.plusDays(

            ChronoUnit.DAYS.between(earliestDateTime, currentDateTime));


    Period p = Period.between(earliestDateTime.toLocalDate(), cut.toLocalDate());

    Duration d = Duration.between(cut, currentDateTime);


    String result = String.format("%s years, %s months, %s days, %s hours, %s minutes, %s seconds",

            p.getYears(), p.getMonths(), p.getDays(),

            d.toHours(), d.toMinutesPart(), d.toSecondsPart());


    System.out.println(result);

當我剛剛運行代碼時,我得到了:

1年4個月13天19小時26分7秒

在現代 Java 日期和時間 API java.time 中,aPeriod是年、月和日Duration的數量,a 是小時、分鐘、秒和秒的小數部分(低至納秒)。既然你想要兩者,我正在使用這兩個類。

我使用的toXxxPart方法Duration是在 Java 9 中引入的。如果您使用的是 Java 8(或 ThreeTen Backport),打印分鐘和秒會稍微復雜一些。搜索java format duration或類似內容以了解如何操作。

我仍然沒有考慮夏季時間。為此,我們需要知道最早運行時間字符串的時區,然后使用ZonedDateTime而不是LocalDateTime. 否則代碼將非常相似。


查看完整回答
反對 回復 2022-10-20
?
智慧大石

TA貢獻1946條經驗 獲得超3個贊

我在 41 年和負數的計算中哪里出錯了?

因為分母會溢出。您需要使用長:

long diffMonths = diff / (30 * 24 * 60 * 60 * 1000L) % 12; //Notice the L at the end
long diffYears = diff / (12 * 30 * 24 * 60 * 60 * 1000L); //Notice the L at the end

另請注意,這12 * 30是一年中天數的一個非常糟糕的近似值。

我有更好的方法嗎?

是的。使用 Java 8 中的 Duration api。https://www.mkyong.com/java8/java-8-period-and-duration-examples/

很難給出準確的答案,因為這個問題有點模糊。例如 - 如果某一年是閏年,并且您正在比較日期 2020/03/28 和 2021/03/28,結果應該是什么?1年還是1年1天?(2020 年是閏年,所以 03/28 之后還有 03/29)


查看完整回答
反對 回復 2022-10-20
?
揚帆大魚

TA貢獻1799條經驗 獲得超9個贊

使用與您相同的方法,您需要將分母明確標識為長值。目前,它假定它們是整數,這會導致數字溢出——這意味著計算的值對于整數來說太大了。這可以解釋為什么你會得到負值/任意值。修復很簡單:


SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.s");

String earliestRunTime = "2017-12-16 01:30:08.0";

Date currentDate = new Date();

log.info("Current Date: {}" + format.format(currentDate));


try {

    Date earliestDate = format.parse(earliestRunTime);


    long diff = currentDate.getTime() - earliestDate.getTime();


    long diffSeconds = diff / 1000L % 60L;

    long diffMinutes = diff / (60L * 1000L) % 60L;

    long diffHours = diff / (60L * 60L * 1000L) % 24L;

    long diffDays = diff / (24L * 60L * 60L * 1000L) % 30L;

    long diffMonths = diff / (30L * 24L * 60L * 60L * 1000L) % 12L;

    long diffYears = diff / (12L * 30L * 24L * 60L * 60L * 1000L);


    return String.format("%s years, %s months, %s days, %s hours, %s minutes, %s seconds",

            diffYears, diffMonths, diffDays, diffHours, diffMinutes, diffSeconds);



}

catch (Exception e) {

    e.printStackTrace();

    return e.getMessage();

}


查看完整回答
反對 回復 2022-10-20
  • 3 回答
  • 0 關注
  • 163 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號