Java 8: Difference between two LocalDateTime in multiple units

后端 未结 10 1679
后悔当初
后悔当初 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 11:43

    Joda-Time

    Since many of the answers required API 26 support and my min API was 23, I solved it by below code :

    import org.joda.time.Days
    
    LocalDate startDate = Something
    LocalDate endDate = Something
    // The difference would be exclusive of both dates, 
    // so in most of use cases we may need to increment it by 1
    Days.daysBetween(startDate, endDate).days
    
    0 讨论(0)
  • 2020-11-22 11:44

    Here a single example using Duration and TimeUnit to get 'hh:mm:ss' format.

    Duration dur = Duration.between(localDateTimeIni, localDateTimeEnd);
    long millis = dur.toMillis();
    
    String.format("%02d:%02d:%02d", 
            TimeUnit.MILLISECONDS.toHours(millis),
            TimeUnit.MILLISECONDS.toMinutes(millis) - 
            TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
            TimeUnit.MILLISECONDS.toSeconds(millis) - 
            TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
    
    0 讨论(0)
  • 2020-11-22 11:45

    I found the best way to do this is with ChronoUnit.

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

    Additional documentation is here: https://docs.oracle.com/javase/tutorial/datetime/iso/period.html

    0 讨论(0)
  • 2020-11-22 11:46

    After more than five years I answer my question. I think that the problem with a negative duration can be solved by a simple correction:

    LocalDateTime fromDateTime = LocalDateTime.of(2014, 9, 9, 7, 46, 45);
    LocalDateTime toDateTime = LocalDateTime.of(2014, 9, 10, 6, 46, 45);
    
    Period period = Period.between(fromDateTime.toLocalDate(), toDateTime.toLocalDate());
    Duration duration = Duration.between(fromDateTime.toLocalTime(), toDateTime.toLocalTime());
    
    if (duration.isNegative()) {
        period = period.minusDays(1);
        duration = duration.plusDays(1);
    }
    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);
    long time[] = {hours, minutes, secs};
    System.out.println(period.getYears() + " years "
                + period.getMonths() + " months "
                + period.getDays() + " days "
                + time[0] + " hours "
                + time[1] + " minutes "
                + time[2] + " seconds.");
    

    Note: The site https://www.epochconverter.com/date-difference now correctly calculates the time difference.

    Thank you all for your discussion and suggestions.

    0 讨论(0)
  • 2020-11-22 11:48

    Here is a very simple answer to your question. It works.

    import java.time.*;
    import java.util.*;
    import java.time.format.DateTimeFormatter;
    import java.time.temporal.ChronoUnit;
    
    public class MyClass {
    public static void main(String args[]) {
        DateTimeFormatter T = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm");
        Scanner h = new Scanner(System.in);
    
        System.out.print("Enter date of birth[dd/mm/yyyy hh:mm]: ");
        String b = h.nextLine();
    
        LocalDateTime bd = LocalDateTime.parse(b,T);
        LocalDateTime cd = LocalDateTime.now();
    
        long minutes = ChronoUnit.MINUTES.between(bd, cd);
        long hours = ChronoUnit.HOURS.between(bd, cd);
    
        System.out.print("Age is: "+hours+ " hours, or " +minutes+ " minutes old");
    }
    }
    
    0 讨论(0)
  • 2020-11-22 11:49

    And the version of @Thomas in Groovy with takes the desired units in a list instead of hardcoding the values. This implementation (which can easily ported to Java - I made the function declaration explicit) makes Thomas approach more reuseable.

    def fromDateTime = LocalDateTime.of(1968, 6, 14, 0, 13, 0)
    def toDateTime = LocalDateTime.now()
    def listOfUnits = [
        ChronoUnit.YEARS, ChronoUnit.MONTHS, ChronoUnit.DAYS,
        ChronoUnit.HOURS, ChronoUnit.MINUTES, ChronoUnit.SECONDS,
        ChronoUnit.MILLIS]
    
    println calcDurationInTextualForm(listOfUnits, fromDateTime, toDateTime)    
    
    String calcDurationInTextualForm(List<ChronoUnit> listOfUnits, LocalDateTime ts, LocalDateTime to)
    {
        def result = []
    
        listOfUnits.each { chronoUnit ->
            long amount = ts.until(to, chronoUnit)
            ts = ts.plus(amount, chronoUnit)
    
            if (amount) {
                result << "$amount ${chronoUnit.toString()}"
            }
        }
    
        result.join(', ')
    }
    

    At the time of this writing,the code above returns 47 Years, 8 Months, 9 Days, 22 Hours, 52 Minutes, 7 Seconds, 140 Millis. And, for @Gennady Kolomoets input, the code returns 23 Hours.

    When you provide a list of units it must be sorted by size of the units (biggest first):

    def listOfUnits = [ChronoUnit.WEEKS, ChronoUnit.DAYS, ChronoUnit.HOURS]
    // returns 2495 Weeks, 3 Days, 8 Hours
    
    0 讨论(0)
提交回复
热议问题