0ne_Up
0ne_Up

Reputation: 501

Calculating time between datetimes

Let's say I have two datetimes, 30-11-2015 10:00 and 02-12-2015 15:00. I also have two times, 07:00 and 22:00. How could I calculate the amount of time passed between the two date/times that was within the second times? Using Calendar object? It seems simple but its boggling my mind.

Upvotes: 3

Views: 139

Answers (2)

Mateusz Korwel
Mateusz Korwel

Reputation: 1148

If you use java8, you can use LocalDateTime. Then your code could looks like this:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalDateTime dateTimeStart = LocalDateTime.parse("2015-10-01 10:00", formatter);
LocalDateTime dateTimeEnd = LocalDateTime.parse("2015-10-02 10:00", formatter);

long seconds = Duration.between(dateTimeStart, dateTimeEnd).getSeconds();

Or LocalTime if you have only time. Then it could looks like this:

LocalTime timeStart = LocalTime.parse("07:00");
LocalTime timeEnd = LocalTime.parse("22:00");

long seconds = Duration.between(timeStart, timeEnd).getSeconds();

If you can't use java8, you can get the number of milliseconds since 1970-01-01 00:00:00 to your date using getTime() method and do simple subtraction operation, like this:

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
Date dateStart = simpleDateFormat.parse("2015-10-01 10:00");
Date dateEnd = simpleDateFormat.parse("2015-10-02 10:00");

long milliseconds = dateEnd.getTime() - dateStart.getTime();
long seconds = resultInMillisecond / 1000;

Upvotes: 0

Gilbert Le Blanc
Gilbert Le Blanc

Reputation: 51445

Since none of the other answers include runnable code, I can't tell if they solve the problem or not.

To calculate the duration of a time range within a date range, you have to:

  • Split the date range into multiple date ranges, each spanning no more than one day.
  • Calculate the time range within each day date range

Taking the example date range from the question. 30-11-2015 10:00 and 02-12-2015 15:00, we generate the following split day date ranges:

30-11-2015 10:00 - 30-11-2015 24:00
01-12-2015 00:00 - 01-12-2015 24:00
02-12-2015 00:00 - 02-12-2015 15:00

Now, we can apply the time range of 7:00 - 22:00 to each of the split day date ranges.

30-11-2015 10:00 - 30-11-2015 24:00 -> 12 hours
01-12-2015 00:00 - 01-12-2015 24:00 -> 15 hours
02-12-2015 00:00 - 02-12-2015 15:00 ->  8 hours

For a total of 35 hours. The actual calculation would probably be in minutes instead of hours.

Edited to add: I created a Time and a TimeRange class to hold the time and a day time range, respectively. I used the java.util.Date, although I had to create my own increment a day method.

I put all of the classes together so I could post this easier. The classes should be put in separate files.

package com.ggl.testing;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class TimeRangeTest {

    private static final SimpleDateFormat inputDateFormat = new SimpleDateFormat(
            "dd-MM-yyyy");

    public static void main(String[] args) {
        TimeRangeTest test = new TimeRangeTest();
        int minutes = test.calculateTotalMinutes("30-11-2015 10:00",
                "02-12-2015 15:00", "07:00", "22:00");
        System.out.println(minutes + " minutes, " + (minutes / 60) + " hours");
    }

    public int calculateTotalMinutes(String startDateTimeString,
            String endDateTimeString, String startTimeString,
            String endTimeString) {
        try {
            List<TimeRange> timeRanges = generateTimeRanges(
                    startDateTimeString, endDateTimeString);
            return calculateTimeRange(timeRanges, startTimeString,
                    endTimeString);
        } catch (ParseException e) {
            e.printStackTrace();
            return 0;
        }
    }

    private List<TimeRange> generateTimeRanges(String startDateTimeString,
            String endDateTimeString) throws ParseException {
        Date startDate = inputDateFormat.parse(startDateTimeString.substring(0,
                10));
        Time startTime = new Time(startDateTimeString.substring(11));
        Date endDate = inputDateFormat
                .parse(endDateTimeString.substring(0, 10));
        Time endTime = new Time(endDateTimeString.substring(11));

        List<TimeRange> timeRanges = new ArrayList<>();

        Date currentDate = new Date(startDate.getTime());
        Time currentTime = new Time(startTime);
        Time eodTime = new Time("24:00");

        while (currentDate.compareTo(endDate) < 0) {
            TimeRange timeRange = new TimeRange(currentDate, currentTime,
                    eodTime);
            timeRanges.add(timeRange);
            currentTime = new Time("00:00");
            currentDate = new Date(currentDate.getTime() + 24L * 60L * 60L
                    * 1000L);
        }

        TimeRange timeRange = new TimeRange(currentDate, currentTime, endTime);
        timeRanges.add(timeRange);

        return timeRanges;
    }

    private int calculateTimeRange(List<TimeRange> timeRanges,
            String startTimeString, String endTimeString) {
        int count = 0;

        Time startTime = new Time(startTimeString);
        Time endTime = new Time(endTimeString);

        for (TimeRange timeRange : timeRanges) {
            Time sodTime = new Time(timeRange.getStartTime());
            Time eodTime = new Time(timeRange.getEndTime());
            Time sTime = startTime.max(sodTime);
            Time eTime = endTime.min(eodTime);

            count += eTime.difference(sTime);
        }

        return count;
    }

    public class TimeRange {

        private final SimpleDateFormat inputDateFormat = new SimpleDateFormat(
                "dd-MM-yyyy");

        private final Date date;

        private final Time startTime;
        private final Time endTime;

        public TimeRange(Date date, Time startTime, Time endTime) {
            this.date = date;
            this.startTime = startTime;
            this.endTime = endTime;
        }

        public Date getDate() {
            return date;
        }

        public Time getStartTime() {
            return startTime;
        }

        public Time getEndTime() {
            return endTime;
        }

        @Override
        public String toString() {
            return inputDateFormat.format(getDate()) + " "
                    + startTime.toString() + " -> " + endTime.toString();
        }

    }

    public class Time {

        private final int minutesPastMidnight;

        public Time(String timeString) {
            int hours = Integer.valueOf(timeString.substring(0, 2));
            int minutes = Integer.valueOf(timeString.substring(3, 5));
            this.minutesPastMidnight = hours * 60 + minutes;
        }

        public Time(Time time) {
            this.minutesPastMidnight = time.getMinutesPastMidnight();
        }

        private int getMinutesPastMidnight() {
            return minutesPastMidnight;
        }

        public int difference(Time time) {
            return this.getMinutesPastMidnight()
                    - time.getMinutesPastMidnight();
        }

        public Time min(Time time) {
            return (difference(time) > 0) ? time : this;
        }

        public Time max(Time time) {
            return (difference(time) > 0) ? this : time;
        }

        @Override
        public String toString() {
            int hours = minutesPastMidnight / 60;
            int minutes = minutesPastMidnight - (hours * 60);
            return String.format("%02d:%02d", hours, minutes);
        }
    }

}

Upvotes: 1

Related Questions