Vidya
Vidya

Reputation: 119

Java method to find difference between 2 date objects in years, months and days

I have a start date and end date. the duration between the 2 dates should be in the form of years, months and days. I am new to java. When I run the below method the out I get is 0 years, 12 months 1 days. Please suggest an alternative to get accurate difference in years, months and days.

import java.sql.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class Duration {

    private String getAssignmentDuration(java.util.Date oldDate, java.util.Date newDate) {
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        if (oldDate.compareTo(newDate) > 0) {
            c1.setTime(newDate);
            c2.setTime(oldDate);
        } else {
            System.out.println("invalid");
            return "Invalid selection";

        }
        int year = 0;
        int month = 0;
        int days = 0;
        boolean doneMonth = false;
        boolean doneYears = false;
        while (c1.before(c2)) {
            //log.debug("Still in Loop");
            if (!doneYears) {
                c1.add(Calendar.YEAR, 1);
                year++;
            }
            if (c1.after(c2) || doneYears) {
                if (!doneYears) {
                    doneYears = true;
                    year--;
                    c1.add(Calendar.YEAR, -1);
                }   
                if (!doneMonth) {
                    c1.add(Calendar.MONTH, 1);
                    month++;
                }
                if (c1.after(c2) || doneMonth) {
                    if (!doneMonth) {
                        doneMonth = true;
                        month--;
                        c1.add(Calendar.MONTH, -1);
                    }

                    c1.add(Calendar.DATE, 1);
                    days++;
                    if (c1.after(c2)) {
                        days--;
                    }
                    // this will not be executed
                    if (days == 31 || month==12) {
                        break;
                    }
                }
            }
        }
        System.out.println(year + " years, " + month + " months, " + days + " days");
        return year + " years, " + month + " months, " + days + " days";

    }


    public static void main(String[] args) {
        Duration d1= new Duration();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
        java.util.Date oldDate = null;
        try {
            oldDate = sdf.parse("2012/08/29");
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        java.util.Date newDate = null;
        try {
            newDate = sdf.parse("2013/08/31");
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        d1.getAssignmentDuration(oldDate, newDate);
    }

}

Upvotes: 3

Views: 19016

Answers (7)

Thirumaran
Thirumaran

Reputation: 499

Simply you could calculate difference between two dates milliseconds and divide by seconds, minutes, hours, days and month

suppose you want to get difference between years try this,

public int findDiff(Date fromDate, Date toDate) {

    if(fromDate == null || toDate == null) {
        return -1;
    }

    long diff = toDate.getTime() - fromDate.getTime();

    int diffInYears = (int) (diff / (60 * 60 * 1000 * 24 * 30.41666666 * 12));
    return diffInYears;
}

suppose you want difference between months remove 12(means months) from the divider. likewise you can get days, hours, minutes..

Upvotes: 0

Basil Bourque
Basil Bourque

Reputation: 338181

tl;dr

Period.between( 
    LocalDate.of( 2017 , Month.JANUARY , 23 ) , 
    LocalDate.of( 2017 , Month.MARCH , 27 ) 
)

Call:

.getYears()
.getMonths()
.getDays()

Avoid legacy date-time classes

You are use troublesome old date-time classes, now legacy, supplanted by java.time classes.

Using java.time

The LocalDate class represents a date-only value without time-of-day and without time zone.

A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );

today.toString(): 2017-05-05

For our example, we create another LocalDate.

LocalDate earlier = today.minusMonths( 2 ).minusWeeks( 3 ).minusDays( 2 ) ;

earlier.toString(): 2017-02-10

To represent a span of time unattached to the timeline in the granularity of years-month-days, use the Period class.

Period p = Period.between( earlier , today ) ;
int years = p.getYears();
int months = p.getMonths();
int days = p.getDays();

See this code run live at IdeOne.com.

ISO 8601

The ISO 8601 standard defines formats for textual representations of date-time values. For durations of years-months-days, the pattern is PnYnMnDTnHnMnS where P marks the beginning and T separates the years-months-days portion from the hours-minutes-seconds portion.

The java.time classes use the standard formats by default when parsing/generating strings. The Period class generates this particular pattern in its toString method.

String output = p.toString() ;

p.toString(): P2M25D

Upvotes: 4

smttsp
smttsp

Reputation: 4191

Assume you have Date date1, date2 and they are initialized where date1>date2.

long diff = date1.getTime() - date2.getTime(); //this is going to give you the difference in milliseconds

Date result = new Date(diff);
Format frmt = new SimpleDateFormat("yy MM dd HH:mm:ss");
return frmt.format(result).toString();//or if you want system.out.println(...);

Upvotes: 3

Joji George
Joji George

Reputation: 1

public static long[] differenceBetweenDates(Date fromDate, Date toDate) {
    Calendar startDate = Calendar.getInstance();
    startDate.setTime(fromDate);
    long years = 0;
    long months = 0;
    long days = 0;
    Calendar endDate = Calendar.getInstance();
    endDate.setTime(toDate);
    Calendar tmpdate = Calendar.getInstance();
    tmpdate.setTime(startDate.getTime());

    tmpdate.add(Calendar.YEAR, 1);
    while (tmpdate.compareTo(endDate) <= 0) {
        startDate.add(Calendar.YEAR, 1);
        tmpdate.add(Calendar.YEAR, 1);
        years++;
    }
    tmpdate.setTime(startDate.getTime());
    tmpdate.add(Calendar.MONTH, 1);
    while (tmpdate.compareTo(endDate) <= 0) {
        startDate.add(Calendar.MONTH, 1);
        tmpdate.add(Calendar.MONTH, 1);
        months++;
    }
    tmpdate.setTime(startDate.getTime());
    tmpdate.add(Calendar.DATE, 1);
    while (tmpdate.compareTo(endDate) <= 0) {
        startDate.add(Calendar.DATE, 1);
        tmpdate.add(Calendar.DATE, 1);
        days++;
    }
    return new long[]{days, months, years};
}

Upvotes: 0

user2640848
user2640848

Reputation: 151

 public static String getDateDifferenceInDDMMYYYY(Date from, Date to) {
        Calendar fromDate=Calendar.getInstance();
        Calendar toDate=Calendar.getInstance();
        fromDate.setTime(from);
        toDate.setTime(to);
        int increment = 0;
        int year,month,day;
        System.out.println(fromDate.getActualMaximum(Calendar.DAY_OF_MONTH));
        if (fromDate.get(Calendar.DAY_OF_MONTH) > toDate.get(Calendar.DAY_OF_MONTH)) {
            increment =fromDate.getActualMaximum(Calendar.DAY_OF_MONTH);
        }
         System.out.println("increment"+increment);
// DAY CALCULATION
        if (increment != 0) {
            day = (toDate.get(Calendar.DAY_OF_MONTH) + increment) - fromDate.get(Calendar.DAY_OF_MONTH);
            increment = 1;
        } else {
            day = toDate.get(Calendar.DAY_OF_MONTH) - fromDate.get(Calendar.DAY_OF_MONTH);
        }

// MONTH CALCULATION
        if ((fromDate.get(Calendar.MONTH) + increment) > toDate.get(Calendar.MONTH)) {
            month = (toDate.get(Calendar.MONTH) + 12) - (fromDate.get(Calendar.MONTH) + increment);
            increment = 1;
        } else {
            month = (toDate.get(Calendar.MONTH)) - (fromDate.get(Calendar.MONTH) + increment);
            increment = 0;
        }

// YEAR CALCULATION
        year = toDate.get(Calendar.YEAR) - (fromDate.get(Calendar.YEAR) + increment);
     return   year+"\tYears\t\t"+month+"\tMonths\t\t"+day+"\tDays";
    }

    public static void main(String[] args) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(1999,01,8);
       /*  Calendar calendar1 = Calendar.getInstance();
        calendar1.set(2012,01,23);*/
        System.out.println(getDateDifferenceInDDMMYYYY(calendar.getTime(),new Date()));
    }

Upvotes: 15

Bhushankumar Lilapara
Bhushankumar Lilapara

Reputation: 780

    long diff = today.getTimeInMillis() - birth.getTimeInMillis();


    // Calculate difference in seconds
    long Seconds = diff / 1000;

    // Calculate difference in minutes
    long Minutes = diff / (60 * 1000);

    // Calculate difference in hours
    long Hours = diff / (60 * 60 * 1000);

    // Calculate difference in days
    long Days = diff / (24 * 60 * 60 * 1000);

    long Months = diff / (24 * 60 * 60 * 12 * 1000);

    //lblTsec, lblTmint, lblthours,lblTdays;
    System.out.println("Seconds : " + Seconds + "");
    System.out.println("Minutes : " + Minutes + "");
    System.out.println("Hours : " + Hours + "");
    System.out.println("Days : " + Days + "");

Upvotes: 1

dan
dan

Reputation: 13262

Joda Time has a concept of time Interval that you can use, like:

Interval interval = new Interval(oldDate.getTime(), newDate.getTime());

Then using a Period object, like:

Period period = interval.toPeriod().normalizedStandard(PeriodType.yearMonthDay());

PeriodFormatter formatter = new PeriodFormatterBuilder()
            .appendYears()
            .appendSuffix(" year ", " years ")
            .appendSeparator(" and ")
            .appendMonths()
            .appendSuffix(" month ", " months ")
            .appendSeparator(" and ")
            .appendDays()
            .appendSuffix(" day ", " days ")
            .toFormatter();
System.out.println(formatter.print(period));

You will easily be able to print your diference in years and months.

Probably you changes something while posting the question, because to fix your code (note that I didn't tested if your code will work with all sort of ranges), you only need to properly initialize the Calendar objects and the reverse the invalid selection check:

Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
if (oldDate.compareTo(newDate) < 0) {
    c2.setTime(newDate);
    c1.setTime(oldDate);
} else {
    System.out.println("invalid");
    return "Invalid selection";
}

Upvotes: 4

Related Questions