219

I want a Java program that calculates days between two dates.

  1. Type the first date (German notation; with whitespaces: "dd mm yyyy")
  2. Type the second date.
  3. The program should calculates the number of days between the two dates.

How can I include leap years and summertime?

My code:

import java.util.Calendar;
import java.util.Date;
import java.util.Scanner;

public class NewDateDifference {

    public static void main(String[] args) {

        System.out.print("Insert first date: ");
        Scanner s = new Scanner(System.in);
        String[] eingabe1 = new String[3];

        while (s.hasNext()) {
            int i = 0;
            insert1[i] = s.next();
            if (!s.hasNext()) {
                s.close();
                break;
            }
            i++;
        }

        System.out.print("Insert second date: ");
        Scanner t = new Scanner(System.in);
        String[] insert2 = new String[3];

        while (t.hasNext()) {
            int i = 0;
            insert2[i] = t.next();
            if (!t.hasNext()) {
                t.close();
                break;
            }
            i++;
        }

        Calendar cal = Calendar.getInstance();

        cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(insert1[0]));
        cal.set(Calendar.MONTH, Integer.parseInt(insert1[1]));
        cal.set(Calendar.YEAR, Integer.parseInt(insert1[2]));
        Date firstDate = cal.getTime();

        cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(insert2[0]));
        cal.set(Calendar.MONTH, Integer.parseInt(insert2[1]));
        cal.set(Calendar.YEAR, Integer.parseInt(insert2[2]));
        Date secondDate = cal.getTime();


        long diff = secondDate.getTime() - firstDate.getTime();

        System.out.println ("Days: " + diff / 1000 / 60 / 60 / 24);
    }
}
6
  • What does not work? Is it crashing? Is it giving you wrong numbers? Commented Nov 23, 2013 at 17:33
  • Where is the declaration of the array: insert1? Commented Nov 23, 2013 at 17:36
  • 3
    insert1 = eingabe1 in German :) Commented Nov 23, 2013 at 17:52
  • @peter.petrov Ah, I see! Commented Nov 23, 2013 at 17:57
  • I think he is having issue with mm and MM :P Commented Nov 23, 2013 at 18:06

18 Answers 18

318

UPDATE

The original answer from 2013 is now outdated because some of the classes have been replaced. The new way of doing this is using the new java.time classes.

24-hour days

DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd MM yyyy");
String inputString1 = "23 01 1997";
String inputString2 = "27 04 1997";

try {
    LocalDateTime date1 = LocalDate.parse(inputString1, dtf);
    LocalDateTime date2 = LocalDate.parse(inputString2, dtf);
    long daysBetween = Duration.between(date1, date2).toDays();
    System.out.println ("Days: " + daysBetween);
} catch (ParseException e) {
    e.printStackTrace();
}

Calendar days

Note that the solution above counts days as generic chunks of 24 hours, not calendar days.

For calendar days, use java.time.temporal.ChronoUnit.DAYS and its between method.

long daysBetween = ChronoUnit.DAYS.between(date1, date2) ;

Original answer (outdated as of Java 8)

You are making some conversions with your Strings that are not necessary. There is a SimpleDateFormat class for it - try this:

SimpleDateFormat myFormat = new SimpleDateFormat("dd MM yyyy");
String inputString1 = "23 01 1997";
String inputString2 = "27 04 1997";

try {
    Date date1 = myFormat.parse(inputString1);
    Date date2 = myFormat.parse(inputString2);
    long diff = date2.getTime() - date1.getTime();
    System.out.println ("Days: " + TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS));
} catch (ParseException e) {
    e.printStackTrace();
}

EDIT

Since there have been some discussions regarding the correctness of this code: it does indeed take care of leap years. However, the TimeUnit.DAYS.convert function loses precision since milliseconds are converted to days (see the linked doc for more info). If this is a problem, diff can also be converted by hand:

float days = (diff / (1000*60*60*24));

Note that this is a float value, not necessarily an int.

Sign up to request clarification or add additional context in comments.

16 Comments

This is a bad implementation that doesn't account leap years properly.
TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS)); <3
@GroovyEd From what I have tested it seems that this code has no problem with leap years. Please take note that TimeUnit.Days.convert() will ignore remaining units eg converting 999 milliseconds to seconds results in 0. This means that if you use new Date() as one of the Date objects you might get one day less so take care
It works for leap years too. check this String inputString1 = "28 2 2016"; String inputString2 = "1 3 2016"; ans: 2
I believe this works correctly for leap years, but it messes up daylight savings time. If your locale has daylight savings time, then every year, there's one day that has 23 hours and one day that has 25 hours. This solution incorrectly assumes that every day has 24 hours. It therefore gives the wrong answer for any period that starts during non-daylight savings and ends during daylight savings. DO NOT USE THIS SOLUTION - there are better ways.
|
149

Simplest way:

public static long getDifferenceDays(Date d1, Date d2) {
    long diff = d2.getTime() - d1.getTime();
    return TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS);
}

7 Comments

Well, basically this is the same as current best answer, though this answer provides it as a function.
Note, that this count only when time interval between two dates are larger than 24 hours (pretty obvious from the code), thus getDifferenceDays(11PM, 4 AM nextday) == 0
this implementation takes the last day as today. For instance, if I run the program with d1 = today, and d2 = yesterday , returns 0 days..
@Nav that's because there are 30 days in June.
This answer is incorrect. It doesn't deal with daylight savings time correctly. Don't use it if you want correct results.
|
107

In Java 8, you could accomplish this by using LocalDate and DateTimeFormatter. From the Javadoc of LocalDate:

LocalDate is an immutable date-time object that represents a date, often viewed as year-month-day.

And the pattern can be constructed using DateTimeFormatter. Here is the Javadoc, and the relevant pattern characters I used:

Symbol - Meaning - Presentation - Examples

y - year-of-era - year - 2004; 04

M/L - month-of-year - number/text - 7; 07; Jul; July; J

d - day-of-month - number - 10

Here is the example:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;

public class Java8DateExample {
    public static void main(String[] args) throws IOException {
        final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd MM yyyy");
        final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        final String firstInput = reader.readLine();
        final String secondInput = reader.readLine();
        final LocalDate firstDate = LocalDate.parse(firstInput, formatter);
        final LocalDate secondDate = LocalDate.parse(secondInput, formatter);
        final long days = ChronoUnit.DAYS.between(firstDate, secondDate);
        System.out.println("Days between: " + days);
    }
}

Example input/output with more recent last:

23 01 1997
27 04 1997
Days between: 94

With more recent first:

27 04 1997
23 01 1997
Days between: -94

Well, you could do it as a method in a simpler way:

public static long betweenDates(Date firstDate, Date secondDate) throws IOException
{
    return ChronoUnit.DAYS.between(firstDate.toInstant(), secondDate.toInstant());
}

4 Comments

Excellent example. This automatically accounts for leap year. If you checked 1991 and 1992 (leap year) it calculates correctly. Perfect!
This should be the current accepted answer. Standard library use and accounts for leap years and daylight savings wont be a problem.
This is the current/modern answer (the others are outdated). It also accounts for summer time (DST). To use on Java 6 or 7, get ThreeTen Backport. On not-new Android ThreeTenABP.
it doesn't take into account daylight saving time
68

Most / all answers caused issues for us when daylight savings time came around. Here's our working solution for all dates, without using JodaTime. It utilizes calendar objects:

public static int daysBetween(Calendar day1, Calendar day2){
    Calendar dayOne = (Calendar) day1.clone(),
            dayTwo = (Calendar) day2.clone();

    if (dayOne.get(Calendar.YEAR) == dayTwo.get(Calendar.YEAR)) {
        return Math.abs(dayOne.get(Calendar.DAY_OF_YEAR) - dayTwo.get(Calendar.DAY_OF_YEAR));
    } else {
        if (dayTwo.get(Calendar.YEAR) > dayOne.get(Calendar.YEAR)) {
            //swap them
            Calendar temp = dayOne;
            dayOne = dayTwo;
            dayTwo = temp;
        }
        int extraDays = 0;

        int dayOneOriginalYearDays = dayOne.get(Calendar.DAY_OF_YEAR);

        while (dayOne.get(Calendar.YEAR) > dayTwo.get(Calendar.YEAR)) {
            dayOne.add(Calendar.YEAR, -1);
            // getActualMaximum() important for leap years
            extraDays += dayOne.getActualMaximum(Calendar.DAY_OF_YEAR);
        }

        return extraDays - dayTwo.get(Calendar.DAY_OF_YEAR) + dayOneOriginalYearDays ;
    }
}

3 Comments

handles daylight saving time switches nicely
+1 for the answer, however, want to add that we need the Calendar dayOne = (Calendar) day1.clone(), dayTwo = (Calendar) day2.clone(); lines since they ensure that the original calendar values aren't overridden. I deleted these lines thinking them redundant and wasted an hour over the fact that my original object's values were getting overwritten from inside this function.
Don't forget that Month value is 0-based in Calendar Class. calendar.set(2015, 11, 30, 0, 00, 00); actually means 30/12/2015
24

The best way, and it converts to a String as bonus ;)

protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    try {
        //Dates to compare
        String CurrentDate=  "09/24/2015";
        String FinalDate=  "09/26/2015";

        Date date1;
        Date date2;

        SimpleDateFormat dates = new SimpleDateFormat("MM/dd/yyyy");

        //Setting dates
        date1 = dates.parse(CurrentDate);
        date2 = dates.parse(FinalDate);

        //Comparing dates
        long difference = Math.abs(date1.getTime() - date2.getTime());
        long differenceDates = difference / (24 * 60 * 60 * 1000);

        //Convert long to String
        String dayDifference = Long.toString(differenceDates);

        Log.e("HERE","HERE: " + dayDifference);
    }
    catch (Exception exception) {
        Log.e("DIDN'T WORK", "exception " + exception);
    }
}

2 Comments

what is possibility of throwing exception ?
Note that this does not work in leap years. For example, from "02/15/2020" to "04/02/2020" is 47 days. This logic will come up with 46.
22

Use:

public int getDifferenceDays(Date d1, Date d2) {
    int daysdiff = 0;
    long diff = d2.getTime() - d1.getTime();
    long diffDays = diff / (24 * 60 * 60 * 1000) + 1;
    daysdiff = (int) diffDays;
    return daysdiff;
}

4 Comments

Does this account for leap years and daylight savings?
@MaxAlexanderHanna it accounts for leap years correctly, but not daylight savings. It only gives the correct answer whenever a period starts during non-daylight savings time but ends during daylight savings. In all other cases, it's off by one.
@saidesh_kilaru What is the "+ 1"? I think you should remove it.
I had a problem that casting to INT resulted in 4 and casting to float resulted in 4.9, so thats not really what I wanted; Maybe not clearly enough described the cases for date1 at 23:59 and date2 at 00:01 and what the expected result would be.
14

Java date libraries are notoriously broken. I would advise to use Joda Time. It will take care of leap year, time zone and so on for you.

Minimal working example:

import java.util.Scanner;
import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.LocalDate;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public class DateTestCase {

    public static void main(String[] args) {

        System.out.print("Insert first date: ");
        Scanner s = new Scanner(System.in);
        String firstdate = s.nextLine();
        System.out.print("Insert second date: ");
        String seconddate = s.nextLine();

        // Formatter
        DateTimeFormatter dateStringFormat = DateTimeFormat
                .forPattern("dd MM yyyy");
        DateTime firstTime = dateStringFormat.parseDateTime(firstdate);
        DateTime secondTime = dateStringFormat.parseDateTime(seconddate);
        int days = Days.daysBetween(new LocalDate(firstTime),
                                    new LocalDate(secondTime)).getDays();
        System.out.println("Days between the two dates " + days);
    }
}

1 Comment

This answer could be improved in a few ways. (a) Specify time zone rather than rely on the JVM's default. So when when creating that DateTimeFormatter, add a call to withZone( DateTimeZone.forID( "Europe/Berlin" ) ). (b) Why use LocalDate in the daysBetween call? Just pass DateTime objects (firstTime, secondTime). For full days, call withTimeAtStartOfDays. (c) I would use variable names firstDateTime rather then firstTime to avoid ambiguity between date, time, and date-time objects. (d) Add some try-catch to handle bad data input that does not match our expected format.
10

If you want to get just days(no times), then you can use ChronoUnit

ChronoUnit.DAYS.between(date1.toLocalDate(), date2.toLocalDate());

Comments

9
String dateStart = "01/14/2015 08:29:58";
String dateStop = "01/15/2015 11:31:48";

//HH converts hour in 24 hours format (0-23), day calculation
SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");

Date d1 = null;
Date d2 = null;

d1 = format.parse(dateStart);
d2 = format.parse(dateStop);

//in milliseconds
long diff = d2.getTime() - d1.getTime();

long diffSeconds = diff / 1000 % 60;
long diffMinutes = diff / (60 * 1000) % 60;
long diffHours = diff / (60 * 60 * 1000) % 24;
long diffDays = diff / (24 * 60 * 60 * 1000);

System.out.print(diffDays + " days, ");
System.out.print(diffHours + " hours, ");
System.out.print(diffMinutes + " minutes, ");
System.out.print(diffSeconds + " seconds.");

Comments

4

We can make use of LocalDate and ChronoUnit java library, Below code is working fine. Date should be in format yyyy-MM-dd.

import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.*;
class Solution {
    public int daysBetweenDates(String date1, String date2) {
        LocalDate dt1 = LocalDate.parse(date1);
        LocalDate dt2= LocalDate.parse(date2);

        long diffDays = ChronoUnit.DAYS.between(dt1, dt2);

        return Math.abs((int)diffDays);
    }
}

2 Comments

Thanks for wanting to contribute. I believe that this good suggestion was already presented in the answer by mkobit.
3

When I run your program, it doesn't even get me to the point where I can enter the second date.

This is simpler and less error prone.

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Test001 {

    public static void main(String[] args) throws Exception {

        BufferedReader br = null;

        br = new BufferedReader(new InputStreamReader(System.in));
        SimpleDateFormat sdf = new SimpleDateFormat("dd MM yyyy");

        System.out.println("Insert first date : ");
        Date dt1 = sdf.parse(br.readLine().trim());

        System.out.println("Insert second date : ");
        Date dt2 = sdf.parse(br.readLine().trim());

        long diff = dt2.getTime() - dt1.getTime();

        System.out.println("Days: " + diff / 1000L / 60L / 60L / 24L);

        if (br != null) {
            br.close();
        }
    }
}

Comments

1
// date format, it will be like "2015-01-01"
private static final String DATE_FORMAT = "yyyy-MM-dd";

// convert a string to java.util.Date
public static Date convertStringToJavaDate(String date)
        throws ParseException {
    DateFormat dataFormat = new SimpleDateFormat(DATE_FORMAT);
    return dataFormat.parse(date);
}

// plus days to a date
public static Date plusJavaDays(Date date, int days) {
    // convert to jata-time
    DateTime fromDate = new DateTime(date);
    DateTime toDate = fromDate.plusDays(days);
    // convert back to java.util.Date
    return toDate.toDate();
}

// return a list of dates between the fromDate and toDate
public static List<Date> getDatesBetween(Date fromDate, Date toDate) {
    List<Date> dates = new ArrayList<Date>(0);
    Date date = fromDate;
    while (date.before(toDate) || date.equals(toDate)) {
        dates.add(date);
        date = plusJavaDays(date, 1);
    }
    return dates;
}

Comments

1

The following works perfectly well for me:

public int daysBetween(LocalDate later, LocalDate before) {
        SimpleDateFormat myFormat = new SimpleDateFormat("dd MM yyyy");
        int daysBetween = 0;
        try {
            Date dateBefore = myFormat.parse(localDateToString(before));
            Date dateAfter = myFormat.parse(localDateToString(later));
            long difference = dateAfter.getTime() - dateBefore.getTime();
            daysBetween = (int) (difference / (1000 * 60 * 60 * 24));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return daysBetween;
    }

    public String localDateToString(LocalDate date) {
        DateTimeFormatter myFormat = DateTimeFormatter.ofPattern("dd MM yyyy");
        return date.format(myFormat).toString();
    }

Comments

1

All the other answers had lots of scary things, here's my simple solution:

public int getDaysDiff(Date dateToCheck) 
{
    long diffMilliseconds = new Date().getTime() - dateToCheck.getTime();
    double diffSeconds = diffMilliseconds / 1000;
    double diffMinutes = diffSeconds / 60;
    double diffHours = diffMinutes / 60;
    double diffDays = diffHours / 24;
        
    return (int) Math.round(diffDays);
}

Comments

0
public class TestCode {

    public static void main(String[] args) {        
        String date1 = "23-04-2021";
        String date2 = "24-05-2021";
        System.out.println("NDays: " + nDays_Between_Dates(date1, date2));      
    }
    
    public static int nDays_Between_Dates(String date1, String date2) {
        int diffDays = 0;
        try {
            SimpleDateFormat dates = new SimpleDateFormat("dd-MM-yyyy");
            Date startDate = dates.parse(date1);
            Date endDate = dates.parse(date2);
            long diff = endDate.getTime() - startDate.getTime();
            diffDays = (int) (diff / (24 * 60 * 60 * 1000));            
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return Math.abs(diffDays);
    }
}

Output: NDays: 31

Comments

0

Use following to covert the timestamp from sql Timestamp values and calculate the date differances.

        SimpleDateFormat dates = new SimpleDateFormat("MM/dd/yyyy");

        //Setting dates
        Date ExDate = dates.parse(dates.format(Timestamp.valueOf(ex_date)));
        Date today = dates.parse(dates.format(new Timestamp(System.currentTimeMillis())));

        //Comparing dates
        long differenceDates = Math.abs(ExDate.getTime() - today.getTime()) / (24 * 60 * 60 * 1000);

        //Convert long to String
        String dayDifference = Long.toString(differenceDates); 
        System.out.println(dayDifference);

Comments

0

Since just the dates are given, without considering the time, we can use ChronoUnit class,

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.Scanner;

class Demo
{
    public static void main(String args[])
    {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd MM yyyy");

        Scanner sc = new Scanner(System.in);
        String s1 = sc.nextLine();
        String s2 = sc.nextLine();

        LocalDate dateBefore = LocalDate.parse(s1, dtf);
        LocalDate dateAfter = LocalDate.parse(s2, dtf);

        System.out.println(ChronoUnit.DAYS.between(dateBefore, dateAfter));
    }
}

1 Comment

what new is this answer adding to the at least 4 years old suggestion from that answer ? Or maybe that one?
-1
public static String dateCalculation(String getTime, String dependTime) {
    //Time A is getTime that need to calculate.
    //Time B is static time that Time A depend on B Time and calculate the result.

    Date date = new Date();
    final SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd H:mm:ss");
    Date dateObj = null;
    Date checkDate = null;

    try {
        dateObj = sdf.parse(getTime);
    } catch (ParseException e) {
        e.printStackTrace();
        return "0";
    }
    SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");

    String checkInDate = dateFormat.format(dateObj).toString();
    Date defaultTime = null;
    try {
        defaultTime = dateFormat.parse(dependTime);
        checkDate = dateFormat.parse(checkInDate);
    } catch (ParseException e) {
        e.printStackTrace();
        return "0";
    }

    try {
        if (dateFormat.parse(dateFormat.format(date)).after(defaultTime)) {
            long diff = checkDate.getTime() - defaultTime.getTime();
            Log.e("Difference", "onBindViewHolder: Difference: " + dateObj + " : " + defaultTime + " : " + diff);
            if (diff > 0) {
                long diffSeconds = diff / 1000 % 60;
                long diffMinutes = diff / (60 * 1000) % 60;
                long diffHours = diff / (60 * 60 * 1000);

                return "Late: " + diffHours + " Hour, " + diffMinutes + " Minutes, " + diffSeconds + " Sec";
            } else {
                return "0";
            }
        }
    } catch (ParseException e) {
        e.printStackTrace();
        return "0";
    }
    return "0";
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.