How to determine the time between now and an arbitrary future date in Java

前端 未结 4 1561
失恋的感觉
失恋的感觉 2020-12-07 05:17

I\'m currently trying to determine the amount of time between two dates (one of which is the present date/time, the other an arbitrary future date). I\'m using native Java a

4条回答
  •  心在旅途
    2020-12-07 06:06

    First I suggest you use library methods for the calculations. For one thing, you should not reinvent the wheel. Second, some of the calculations may get tricky, for example if you also want to report months or years and need to take different month lengths and leap years into account. Not least, while it’s easy to divide by 60 for converting from seconds to minutes while writing the code, while reading it a method name that has ‘minutes’ or ‘seconds’ in it will more clearly convey why you are dividing by 60.

    These days Java has two classes for amounts of time:

    • Duration is for time between clock times, for example 2 hours 46 minutes 30 seconds (it can handle days too, but knows neither weeks nor months).
    • Period is for time between dates, for example 2 months 9 days.

    For a general solution I will show how you may use both for your task. I first find the Period between the dates. If that is from today at 2 PM to the day after tomorrow at 10 AM, you will get two days where we wanted 1 day 20 hours, so we need to adjust for that by subtracting 1 day before calculating the Duration.

        LocalDateTime dateTimeOne = LocalDateTime.of(2016, Month.APRIL, 25, 9, 5, 30);
        LocalDateTime dateTimeTwo = LocalDateTime.of(2017, Month.MAY, 15, 9, 10, 50);
    
        Period p = Period.between(dateTimeOne.toLocalDate(), dateTimeTwo.toLocalDate());
        LocalDateTime dtOnePlusPeriod = dateTimeOne.plus(p);
        if (dtOnePlusPeriod.isAfter(dateTimeTwo)) { // too far
            p = p.minusDays(1);
        }
        Duration d = Duration.between(dateTimeOne.plus(p), dateTimeTwo);
    
        long hours = d.toHours();
        d = d.minusHours(hours);
        long minutes = d.toMinutes();
        d = d.minusMinutes(minutes);
        long seconds = d.getSeconds();
    
        if (p.isZero() && d.isZero()) {
            System.out.println("0 seconds");
        } else {
            if (p.getYears() != 0) {
                System.out.print("" + p.getYears() + " years ");
            }
            if (p.getMonths() != 0) {
                System.out.print("" + p.getMonths() + " months ");
            }
            if (p.getDays() != 0) {
                System.out.print("" + p.getDays() + " days ");
            }
            if (hours != 0) {
                System.out.print("" + hours + " hours ");
            }
            if (minutes != 0) {
                System.out.print("" + minutes + " minutes ");
            }
            if (seconds != 0) {
                System.out.print("" + seconds + " seconds");
            }
            System.out.println();
        }
    

    This prints

    1 years 20 days 5 minutes 20 seconds
    

    By using LocalDateTime I am ignoring changes to and from summer time (DST). If you need to take these into account, just use ZonedDateTime instead.

    All the classes are in the java.time package. I will include a link to the Oracle tutorial at the bottom.

    If you want to use java.time on Android, you get them in the ThreeTenABP. More links below.

    With Java 9 will come some new methods in Duration, toHoursPart(), toMinutesPart() and toSecondsPart() that will give us the hours, minutes and seconds we want, much the way I have already done with Period. Then we will no longer need to subtract first the hours and then the minutes while calculating the indivivual fields.

    Links

    • Oracle Tutorial: Trail: Date Time
    • ThreeTenABP
    • Question: How to use ThreeTenABP in Android Project, a thorough getting started guide

提交回复
热议问题