Java 8: 两个 LocalDateTime 之间多个单位的差异

13 浏览
0 Comments

Java 8: 两个 LocalDateTime 之间多个单位的差异

我正在尝试计算两个LocalDateTime之间的差异。\n输出需要以\"y years m months d days h hours m minutes s seconds\"的格式呈现。以下是我编写的代码:\n

import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.Period;
import java.time.ZoneId;
public class Main {
    static final int MINUTES_PER_HOUR = 60;
    static final int SECONDS_PER_MINUTE = 60;
    static final int SECONDS_PER_HOUR = SECONDS_PER_MINUTE * MINUTES_PER_HOUR;
    public static void main(String[] args) {
        LocalDateTime toDateTime = LocalDateTime.of(2014, 9, 9, 19, 46, 45);
        LocalDateTime fromDateTime = LocalDateTime.of(1984, 12, 16, 7, 45, 55);
        Period period = getPeriod(fromDateTime, toDateTime);
        long time[] = getTime(fromDateTime, toDateTime);
        System.out.println(period.getYears() + " years " + 
                period.getMonths() + " months " + 
                period.getDays() + " days " +
                time[0] + " hours " +
                time[1] + " minutes " +
                time[2] + " seconds.");
    }
    private static Period getPeriod(LocalDateTime dob, LocalDateTime now) {
        return Period.between(dob.toLocalDate(), now.toLocalDate());
    }
    private static long[] getTime(LocalDateTime dob, LocalDateTime now) {
        LocalDateTime today = LocalDateTime.of(now.getYear(),
                now.getMonthValue(), now.getDayOfMonth(), dob.getHour(), dob.getMinute(), dob.getSecond());
        Duration duration = Duration.between(today, now);
        long seconds = duration.getSeconds();
        long hours = seconds / SECONDS_PER_HOUR;
        long minutes = ((seconds % SECONDS_PER_HOUR) / SECONDS_PER_MINUTE);
        long secs = (seconds % SECONDS_PER_MINUTE);
        return new long[]{hours, minutes, secs};
    }
}

\n我得到的输出结果是\"29 years 8 months 24 days 12 hours 0 minutes 50 seconds\"。我已经从这个网站(使用值\"12/16/1984 07:45:55\"和\"09/09/2014 19:46:45\")验证了我的结果。以下是截图:\n\"Epoch\n我非常确定月份后面的字段在我的代码中是错误的。任何建议都将非常有帮助。\n

更新

\n我已经从另一个网站测试了我的结果,得到的结果是不同的。这是它:计算两个日期之间的时长(结果:29年8个月24天12小时0分钟50秒)。\n

更新

\n由于我从两个不同的网站得到了两个不同的结果,我想知道我的计算算法是否合法。如果我使用以下两个LocalDateTime对象:\n

LocalDateTime toDateTime = LocalDateTime.of(2014, 9, 10, 6, 40, 45);
LocalDateTime fromDateTime = LocalDateTime.of(1984, 12, 16, 7, 45, 55);

\n那么输出结果是:\"29 years 8 months 25 days -1 hours -5 minutes -10 seconds.\"。\n从这个链接中应该是\"29 years 8 months 24 days 22 hours, 54 minutes and 50 seconds\"。所以算法需要处理负数。\n请注意,问题不是哪个网站给我什么结果,我需要知道正确的算法并得到正确的结果。

0
0 Comments

问题的出现原因是在Java 8之前,计算两个LocalDateTime之间的时间差需要编写更多的代码。解决方法是使用Duration.between()方法来计算时间差,然后通过toMillis()方法将时间差转换为毫秒。接着可以使用TimeUnit类的静态方法将毫秒转换为其他单位,比如分钟和秒。最后,通过String.format方法将转换后的时间差格式化输出。这种解决方法在Java 8中是语义上正确的,并且在之前的版本中,JodaTime也是采用了相同的解决方案。

0
0 Comments

问题的出现原因:

在Java 8中,没有一个时间段(period)类可以跨越时间,因此需要自己进行计算。

解决方法:

幸运的是,日期和时间类有很多实用方法可以简化计算。以下是一种计算时间差的方法,虽然不一定是最快的方法:

LocalDateTime fromDateTime = LocalDateTime.of(1984, 12, 16, 7, 45, 55);
LocalDateTime toDateTime = LocalDateTime.of(2014, 9, 10, 6, 40, 45);
LocalDateTime tempDateTime = LocalDateTime.from( fromDateTime );
long years = tempDateTime.until( toDateTime, ChronoUnit.YEARS );
tempDateTime = tempDateTime.plusYears( years );
long months = tempDateTime.until( toDateTime, ChronoUnit.MONTHS );
tempDateTime = tempDateTime.plusMonths( months );
long days = tempDateTime.until( toDateTime, ChronoUnit.DAYS );
tempDateTime = tempDateTime.plusDays( days );
long hours = tempDateTime.until( toDateTime, ChronoUnit.HOURS );
tempDateTime = tempDateTime.plusHours( hours );
long minutes = tempDateTime.until( toDateTime, ChronoUnit.MINUTES );
tempDateTime = tempDateTime.plusMinutes( minutes );
long seconds = tempDateTime.until( toDateTime, ChronoUnit.SECONDS );
System.out.println( years + " years " + 
        months + " months " + 
        days + " days " +
        hours + " hours " +
        minutes + " minutes " +
        seconds + " seconds.");
//输出结果:29 years 8 months 24 days 22 hours 54 minutes 50 seconds.

基本思路是这样的:创建一个临时的开始日期,获取到结束日期的完整年份。然后通过年数调整日期,使得开始日期距离结束日期不到一年。以此类推,依次处理每个时间单位。

最后需要说明的是,这个方法没有考虑不同的时区(两个日期应该在同一个时区),也没有测试/检查夏令时或其他日历变化(比如萨摩亚时区的变化)对计算的影响。所以请谨慎使用。

0
0 Comments

Java 8: 两个LocalDateTime之间的多个单位的差异

在Java 8中,我们可以使用ChronoUnit来计算两个LocalDateTime之间的差异。下面的代码展示了如何使用ChronoUnit来计算分钟和小时之间的差异:

long minutes = ChronoUnit.MINUTES.between(fromDate, toDate);
long hours = ChronoUnit.HOURS.between(fromDate, toDate);

使用ChronoUnit进行日期差异计算的更多文档可以在这里找到:[Period and Duration](https://docs.oracle.com/javase/tutorial/datetime/iso/period.html)

然而,有一些人对这种方法表示了质疑。他们认为这种方法并没有真正改进。相较于Thomas的答案,只是将`tempDateTime.until( toDateTime, ChronoUnit.YEARS)`替换为`ChronoUnit.YEARS.between(fromDate, toDate)`。但是,重要的附加行,如`tempDateTime.plusYears( years )`等,在这个答案中完全缺失,因此对于提问者并没有真正帮助。完整的算法才是关键!

然而,还有一些人认为这种方法更简洁、更易读。他们认为这是找到两个日期之间差异的最佳方法。

对此,还有人提出异议,认为他们才是关键。提问者已经在一年多前得到了他们的答案。阅读此问题的36,000人并不关心提问者的具体问题。他们是通过谷歌搜索到这里的,而我的答案为他们提供了他们所寻找的干净简洁的解决方案,即计算两个日期之间的差异。

另外,有人认为许多人误解了问题。他们认为`ChronoUnit.between(...)`并不是什么新东西,可以在Stack Overflow上找到多次,例如:与JSR-310的主要作者的回答的示例链接

还有人分享了他们自己的解决方案,以获得两个日期时间之间的秒差异。他们表示自己的解决方案很复杂,于是上网搜索了解决方法。虽然satnam的答案可能并没有回答到提问者的问题,但对于他们和其他许多人来说,这确实帮了很大的忙。

总之,在这个问题中,有一些人认为ChronoUnit是计算两个LocalDateTime之间差异的最佳方法,而另一些人则认为这种方法并没有真正解决提问者的问题。不过,无论怎样,这个问题和讨论都为我们提供了不同的思考和学习的机会。

0