Java 8: Difference between two LocalDateTime in multiple units

后端 未结 10 1807
后悔当初
后悔当初 2020-11-22 11:36

I am trying to calculate the difference between two LocalDateTime.

The output needs to be of the format y years m months d days h hours m minutes

10条回答
  •  爱一瞬间的悲伤
    2020-11-22 12:09

    TL;DR

    Duration duration = Duration.between(start, end);
    duration = duration.minusDays(duration.toDaysPart()); // essentially "duration (mod 1 day)"
    Period period = Period.between(start.toLocalDate(), end.toLocalDate());
    

    and then use the methods period.getYears(), period.getMonths(), period.getDays(), duration.toHoursPart(), duration.toMinutesPart(), duration.toSecondsPart().


    Expanded answer

    I'll answer the original question, i.e. how to get the time difference between two LocalDateTimes in years, months, days, hours & minutes, such that the "sum" (see note below) of all the values for the different units equals the total temporal difference, and such that the value in each unit is smaller than the next bigger unit—i.e. minutes < 60, hours < 24, and so on.

    Given two LocalDateTimes start and end, e.g.

    LocalDateTime start = LocalDateTime.of(2019, 11, 29, 17, 15);
    LocalDateTime end = LocalDateTime.of(2020, 11, 30, 18, 44);
    

    we can represent the absolute timespan between the two with a Duration—perhaps using Duration.between(start, end). But the biggest unit we can extract out of a Duration is days (as a temporal unit equivalent to 24h)—see the note below for an explanation. To use larger units (months, years) we can represent this Duration with a pair of (Period, Duration), where the Period measures the difference up to a precision of days and the Duration represents the remainder:

    Duration duration = Duration.between(start, end);
    duration = duration.minusDays(duration.toDaysPart()); // essentially "duration (mod 1 day)"
    Period period = Period.between(start.toLocalDate(), end.toLocalDate());
    

    Now we can simply use the methods defined on Period and Duration to extract the individual units:

    System.out.printf("%d years, %d months, %d days, %d hours, %d minutes, %d seconds",
            period.getYears(), period.getMonths(), period.getDays(), duration.toHoursPart(),
            duration.toMinutesPart(), duration.toSecondsPart());
    
    1 years, 0 months, 1 days, 1 hours, 29 minutes, 0 seconds
    

    or, using the default format:

    System.out.println(period + " + " + duration);
    
    P1Y1D + PT1H29M
    

    Note on years, months & days

    Note that, in java.time's conception, "units" like "month" or "year" don't represent a fixed, absolute temporal value—they're date- and calendar-dependent, as the following example illustrates:

    LocalDateTime
            start1 = LocalDateTime.of(2020, 1, 1, 0, 0),
            end1 = LocalDateTime.of(2021, 1, 1, 0, 0),
            start2 = LocalDateTime.of(2021, 1, 1, 0, 0),
            end2 = LocalDateTime.of(2022, 1, 1, 0, 0);
    System.out.println(Period.between(start1.toLocalDate(), end1.toLocalDate()));
    System.out.println(Duration.between(start1, end1).toDays());
    System.out.println(Period.between(start2.toLocalDate(), end2.toLocalDate()));
    System.out.println(Duration.between(start2, end2).toDays());
    
    P1Y
    366
    P1Y
    365
    

提交回复
热议问题