498

I'm using Java's java.util.Date class in Scala and want to compare a Date object and the current time. I know I can calculate the delta by using getTime():

(new java.util.Date()).getTime() - oldDate.getTime()

However, this just leaves me with a long representing milliseconds. Is there any simpler, nicer way to get a time delta?

trent
  • 25,033
  • 7
  • 51
  • 90
pr1001
  • 21,727
  • 17
  • 79
  • 125
  • 12
    Why no love for joda time? It's pretty much the best option if you're going to deal with dates in java. – Doctor Jones May 03 '12 at 11:14
  • 9
    Please check my elegant 2 liner solution, without using Joda and giving the result in any TimeUnit at http://stackoverflow.com/a/10650881/82609 – Sebastien Lorber Mar 12 '13 at 11:19
  • try this: http://www.mkyong.com/java/how-to-calculate-date-time-difference-in-java/ – deldev Jul 23 '14 at 17:54
  • 8
    Shame on all those who recommend Joda time, and don't recommending a true Java answer... – Zizouz212 Dec 30 '15 at 14:49
  • For most of the solutions outlined here and elsewhere, they are inaccurate when Daylight savings time (DST) is taken into account. Indeed, when 24 hours are added to Saturday 2016-03-26T23:30 CET, the resulting date is 2016-03-28T00:30 CET and two day frontiers are crossed, Indeed, DST goes into effect on Sunday 2016-03-27T02:00 Central European Time. The DST issue is not specific to CET and occurs each tme the period being considered contains DST going into effect. – Ceki Mar 18 '16 at 10:32
  • 5
    @Zizouz212 Regarding recommending Joda-Time, the old date-time classes bundled with Java are bad, real bad, poorly-designed, confusing, and troublesome. So bad that Joda-Time became hugely successful as their replacement. So bad that even Sun/Oracle gave up on them, and adopted the java.time package as part of Java 8 and later. The java.time classes are inspired by Joda-Time. Both Joda-Time and java.time are led by the same man, [Stephen Colbourne](http://stackoverflow.com/users/38896/jodastephen). I would say, “Shame on anyone recommending use of `Date`, `Calendar`, and `SimpleDateFormat`”. – Basil Bourque Oct 26 '16 at 19:43
  • @BasilBourque OP asked for a "simpler, nicer way to get a time delta"; a quick, two line diff seems simpler/nicer than requiring an external dependency. – plátano plomo Nov 11 '16 at 23:17
  • 4
    While Joda Time was probably a good answer when the question was asked, today the best answer for anyone who can use Java 8 is to use `java.time.Period` and/or `Duration`. See [Basil Bourque’s answer below](http://stackoverflow.com/a/22588328/5772882). – Ole V.V. Feb 16 '17 at 08:46
  • 1
    You may also look at [Calculate days between two dates in Java 8](http://stackoverflow.com/questions/27005861/calculate-days-between-two-dates-in-java-8). And still avoid any external dependency. – Ole V.V. Apr 12 '17 at 10:57

46 Answers46

615

Simple diff (without lib)

/**
 * Get a diff between two dates
 * @param date1 the oldest date
 * @param date2 the newest date
 * @param timeUnit the unit in which you want the diff
 * @return the diff value, in the provided unit
 */
public static long getDateDiff(Date date1, Date date2, TimeUnit timeUnit) {
    long diffInMillies = date2.getTime() - date1.getTime();
    return timeUnit.convert(diffInMillies,TimeUnit.MILLISECONDS);
}

And then you can call:

getDateDiff(date1,date2,TimeUnit.MINUTES);

to get the diff of the 2 dates in minutes unit.

TimeUnit is java.util.concurrent.TimeUnit, a standard Java enum going from nanos to days.


Human readable diff (without lib)

public static Map<TimeUnit,Long> computeDiff(Date date1, Date date2) {

    long diffInMillies = date2.getTime() - date1.getTime();

    //create the list
    List<TimeUnit> units = new ArrayList<TimeUnit>(EnumSet.allOf(TimeUnit.class));
    Collections.reverse(units);

    //create the result map of TimeUnit and difference
    Map<TimeUnit,Long> result = new LinkedHashMap<TimeUnit,Long>();
    long milliesRest = diffInMillies;

    for ( TimeUnit unit : units ) {
        
        //calculate difference in millisecond 
        long diff = unit.convert(milliesRest,TimeUnit.MILLISECONDS);
        long diffInMilliesForUnit = unit.toMillis(diff);
        milliesRest = milliesRest - diffInMilliesForUnit;

        //put the result in the map
        result.put(unit,diff);
    }

    return result;
}

http://ideone.com/5dXeu6

The output is something like Map:{DAYS=1, HOURS=3, MINUTES=46, SECONDS=40, MILLISECONDS=0, MICROSECONDS=0, NANOSECONDS=0}, with the units ordered.

You just have to convert that map to a user-friendly string.


Warning

The above code snippets compute a simple diff between 2 instants. It can cause problems during a daylight saving switch, like explained in this post. This means if you compute the diff between dates with no time you may have a missing day/hour.

In my opinion the date diff is kind of subjective, especially on days. You may:

  • count the number of 24h elapsed time: day+1 - day = 1 day = 24h

  • count the number of elapsed time, taking care of daylight savings: day+1 - day = 1 = 24h (but using midnight time and daylight savings it could be 0 day and 23h)

  • count the number of day switches, which means day+1 1pm - day 11am = 1 day, even if the elapsed time is just 2h (or 1h if there is a daylight saving :p)

My answer is valid if your definition of date diff on days match the 1st case

With JodaTime

If you are using JodaTime you can get the diff for 2 instants (millies backed ReadableInstant) dates with:

Interval interval = new Interval(oldInstant, new Instant());

But you can also get the diff for Local dates/times:

// returns 4 because of the leap year of 366 days
new Period(LocalDate.now(), LocalDate.now().plusDays(365*5), PeriodType.years()).getYears() 

// this time it returns 5
new Period(LocalDate.now(), LocalDate.now().plusDays(365*5+1), PeriodType.years()).getYears() 

// And you can also use these static methods
Years.yearsBetween(LocalDate.now(), LocalDate.now().plusDays(365*5)).getYears()
Sebastien Lorber
  • 89,644
  • 67
  • 288
  • 419
  • Wow, you really can teach an old dog new tricks! Never heard of this before, very useful for translating date differences into meaningful strings. – Jeremy Goodell Mar 03 '14 at 16:32
  • @SebastienLorber Is there a way in TimeUnit to calculate the difference thus? "The alarm is set for 3 days, 4 hours and 12 minutes from now". – likejudo Apr 15 '14 at 01:21
  • brilliant stuff really saved lots of my time. Appreciate your help. – Lyju I Edwinson Aug 25 '14 at 11:36
  • I wasted a 3 days of my life dealing with Java Dates and I just threw a lot of it away and replaced with this. Thank you. – user1091524 May 02 '15 at 22:10
  • This is the best answer that i've seen since i came on stackoverflow! :D:D:D – Cold Jul 06 '15 at 16:03
  • the blog post you refer to cannot be viewed unfortunately? – Stefan Hendriks Apr 05 '18 at 08:38
  • what if start date's hour was 10 p.m and end day hour was 12 a.m ?? You need to take hours and minutes in account also! – M22 Nov 27 '21 at 20:30
  • This will work sometimes, but it's not going to give the correct number of days if daylight savings starts or ends between the two dates. Don't be fooled by 600 upvotes - do not use this answer. – Dawood ibn Kareem Mar 09 '22 at 20:11
214

The JDK Date API is horribly broken unfortunately. I recommend using Joda Time library.

Joda Time has a concept of time Interval:

Interval interval = new Interval(oldTime, new Instant());

EDIT: By the way, Joda has two concepts: Interval for representing an interval of time between two time instants (represent time between 8am and 10am), and a Duration that represents a length of time without the actual time boundaries (e.g. represent two hours!)

If you only care about time comparisions, most Date implementations (including the JDK one) implements Comparable interface which allows you to use the Comparable.compareTo()

JodaStephen
  • 60,927
  • 15
  • 95
  • 117
notnoop
  • 58,763
  • 21
  • 123
  • 144
  • btw -- you mean `Comparable.compareTo()`, not `Comparable.compare()`. – Scott Morrison Dec 13 '10 at 04:33
  • Joda-Time has three classes to portray a span of time in various ways: Interval, Duration, and Period. This correct answer discusses this first two. See [my answer](http://stackoverflow.com/a/22588328/642706) for info about Period. – Basil Bourque Jun 25 '14 at 16:55
  • Java 8 has a new date and time api like joda. – tbodt Jun 25 '14 at 23:30
  • 14
    The new [`java.time`](http://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html) package in Java 8 is inspired by Joda-Time but is not a drop-in replacement. Each has its pros and cons. Fortunately you don't have to choose between them. Use each for its strengths as long as you are careful with your `import` statements. See [this other answer](http://stackoverflow.com/a/23184523/642706) for example of java.time. – Basil Bourque Jun 26 '14 at 06:28
  • 7
    FYI, the [Joda-Time](http://www.joda.org/joda-time/) project is now in [maintenance mode](https://en.wikipedia.org/wiki/Maintenance_mode), with the team advising migration to the [java.time](http://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html) classes. See [Tutorial by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque May 05 '17 at 03:15
  • How to convert LocalDatee to ReadableInstant? – Vishesh Mar 17 '22 at 21:08
161
int diffInDays = (int)( (newerDate.getTime() - olderDate.getTime()) 
                 / (1000 * 60 * 60 * 24) )

Note that this works with UTC dates, so the difference may be a day off if you look at local dates. And getting it to work correctly with local dates requires a completely different approach due to daylight savings time.

Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
  • 6
    This actually does not work correctly in Android. Rounding errors exist. Example 19th to 21st May says 1 day because it casts 1.99 to 1. Use round before casting to int. – Pratik Mandrekar May 01 '13 at 14:51
  • 4
    This is the best and simplest answer. When calculating a difference between two dates, local time zones subtract each other out ... so that the correct answer (as a double) is given simply by ((double) (newer.getTime() - older.getTime()) / (86400.0 * 1000.0); ... as a double, you have the fractional day as well which can easily be converted to HH:MM:ss. – scottb May 16 '13 at 04:53
  • 8
    @scottb: the problem with local dates is that you can have daylight savings time, which means some days have 23 or 25 hours, potentially messing up the result. – Michael Borgwardt May 16 '13 at 09:27
  • 1
    @Steve: it's 28 for me when defining them like this new Date(115, 2, 26); (pay attention to the API doc for the params). Is it possible that you are parsing them using the US date format and in lenient mode, so that 26/03/2015 is interpreted as the 3rd day of the 26th month of 2015? – Michael Borgwardt Apr 07 '15 at 07:42
  • Sorry it was -21 not 1: `Date startDate = new Date();` `Date endDate = new Date();` `DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");` `int rosterDays = 0;` `try` `{` `startDate = formatter.parse("26/02/2015");` `endDate = formatter.parse("26/03/2015");` `rosterDays = (int)(endDate.getTime() - startDate.getTime()) / ((1000 * 60 * 60 * 24));` `}` `catch (ParseException e)` `{}` `System.out.println("rosterDays = " + rosterDays);` Sorry for the formatting, I cant see how to format it better! – Steve Apr 09 '15 at 03:51
  • @Steve: when I run that exact code, the output is 28. It's locale-dependant, but I can't really see how it could ever output -21. What do you get when you run System.out.println(Locale.getDefault(Locale.Category.FORMAT));? – Michael Borgwardt Apr 09 '15 at 07:28
  • Hey Michael, I get "en_AU" when outputting the Locale. Here is the full code on PasteBin: http://pastebin.com/QQjU2T4k – Steve Apr 13 '15 at 00:36
  • 1
    @Steve: hm, not sure why I got a different result before, but now I can reproduce your error. The braces in your code are different than in my answer, which causes `(endDate.getTime() - startDate.getTime())` to be cast to `int` instead of the final result, and you're getting an integer overflow. – Michael Borgwardt Apr 13 '15 at 07:48
  • 1
    I just needed to count the seconds and milliseconds for a simple performance time check, i did `double diffInSeconds = ((after.getTime() - b4.getTime()) / 1000d);` – Joey Baruch Mar 01 '17 at 11:37
  • `getTime()` returns a long, so it is probably better to use a long in these calculations. – ThomasW Apr 28 '17 at 10:43
77

Using the java.time framework built into Java 8+:

ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime oldDate = now.minusDays(1).minusMinutes(10);
Duration duration = Duration.between(oldDate, now);
System.out.println("ISO-8601: " + duration);
System.out.println("Minutes: " + duration.toMinutes());

Output:

ISO-8601: PT24H10M

Minutes: 1450

For more info, see the Oracle Tutorial and the ISO 8601 standard.

Community
  • 1
  • 1
Vitalii Fedorenko
  • 110,878
  • 29
  • 149
  • 111
67

tl;dr

Convert your obsolete java.util.Date objects to their replacement, java.time.Instant. Then calculate the elapsed time as a Duration.

Duration d = 
    Duration.between(                   // Calculate the span of time between two moments as a number of hours, minutes, and seconds.
        myJavaUtilDate.toInstant() ,    // Convert legacy class to modern class by calling new method added to the old class.
        Instant.now()                   // Capture the current moment in UTC. About two and a half hours later in this example.
    )
;

d.toString(): PT2H34M56S

d.toMinutes(): 154

d.toMinutesPart(): 34

ISO 8601 Format: PnYnMnDTnHnMnS

The sensible standard ISO 8601 defines a concise textual representation of a span of time as a number of years, months, days, hours, etc. The standard calls such such a span a duration. The format is PnYnMnDTnHnMnS where the P means "Period", the T separates the date portion from the time portion, and in between are numbers followed by a letter.

Examples:

  • P3Y6M4DT12H30M5S
    three years, six months, four days, twelve hours, thirty minutes, and five seconds
  • PT4H30M
    Four and a half hours

java.time

The java.time framework built into Java 8 and later supplants the troublesome old java.util.Date/java.util.Calendar classes. The new classes are inspired by the highly successful Joda-Time framework, intended as its successor, similar in concept but re-architected. Defined by JSR 310. Extended by the ThreeTen-Extra project. See the Tutorial.

Moment

The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).

Instant instant = Instant.now() ;  // Capture current moment in UTC.

Best to avoid the legacy classes such as Date/Calendar. But if you must inter-operate with old code not yet updated to java.time, convert back and forth. Call new conversion methods added to the old classes. For moving from a java.util.Date to an Instant, call Date::toInstant.

Instant instant = myJavaUtilDate.toInstant() ;  // Convert from legacy `java.util.Date` class to modern `java.time.Instant` class.

Span of time

The java.time classes have split this idea of representing a span of time as a number of years, months, days, hours, minutes, seconds into two halves:

  • Period for years, months, days
  • Duration for days, hours, minutes, seconds

Here is an example.

ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now ( zoneId );
ZonedDateTime future = now.plusMinutes ( 63 );
Duration duration = Duration.between ( now , future );

Dump to console.

Both Period and Duration use the ISO 8601 standard for generating a String representation of their value.

System.out.println ( "now: " + now + " to future: " + now + " = " + duration );

now: 2015-11-26T00:46:48.016-05:00[America/Montreal] to future: 2015-11-26T00:46:48.016-05:00[America/Montreal] = PT1H3M

Java 9 adds methods to Duration to get the days part, hours part, minutes part, and seconds part.

You can get the total number of days or hours or minutes or seconds or milliseconds or nanoseconds in the entire Duration.

long totalHours = duration.toHours();

In Java 9 the Duration class gets new methods for returning the various parts of days, hours, minutes, seconds, milliseconds/nanoseconds. Call the to…Part methods: toDaysPart(), toHoursPart(), and so on.

ChronoUnit

If you only care about a simpler larger granularity of time, such as “number of days elapsed”, use the ChronoUnit enum.

long daysElapsed = ChronoUnit.DAYS.between( earlier , later );

Another example.

Instant now = Instant.now();
Instant later = now.plus( Duration.ofHours( 2 ) );
…
long minutesElapsed = ChronoUnit.MINUTES.between( now , later );

120


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to java.time.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

  • Java SE 8 and SE 9 and later
    • Built-in.
    • Part of the standard Java API with a bundled implementation.
    • Java 9 adds some minor features and fixes.
  • Java SE 6 and SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.


Joda-Time

UPDATE: The Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes. I leave this section intact for history.

The Joda-Time library uses ISO 8601 for its defaults. Its Period class parses and generates these PnYnMnDTnHnMnS strings.

DateTime now = DateTime.now(); // Caveat: Ignoring the important issue of time zones.
Period period = new Period( now, now.plusHours( 4 ).plusMinutes( 30));
System.out.println( "period: " + period );

Renders:

period: PT4H30M
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
  • It's funny you started an irrelevant-to-question wall of text with "tl; dr". The question isn't about how to get the timestamp from X ago or in X units of time, but how to get the delta between two dates. That's it. – Buffalo Mar 19 '18 at 12:51
  • @Buffalo I don’t understand your comment. My Answer involves `Period`, `Duration`, and `ChronoUnit`, three classes whose purpose is determining the delta between points of time. Please indicate which parts of my “wall of text” are irrelevant. And you are incorrect in saying the Question asked for a “delta between dates”: The Question asked for a delta between `Date` objects, which are date-time moments, not “dates” despite the unfortunate naming of that class. – Basil Bourque Mar 19 '18 at 15:14
  • There is nothing in your comment that handles two existing java.util.Date objects. I tried using various snippets in my code and found nothing that uses a java.util.Date object. – Buffalo Mar 21 '18 at 08:01
  • @Buffalo Fair enough, good criticism. I added code in the "tl;dr" section converting from a `java.util.Date` to an `Instant` (just call `.toInstant`). And I added the `Moment` section to explain. You mentioned a pair of `Date` objects, but actually the Question uses only a single existing `Date` object and then captures the current moment, so I did the same. Thanks for the feedback! Tip: Give up on using `Date` – Those legacy classes really are an awful wretched mess. – Basil Bourque Mar 21 '18 at 08:29
54

You need to define your problem more clearly. You could just take the number of milliseconds between the two Date objects and divide by the number of milliseconds in 24 hours, for example... but:

  • This won't take time zones into consideration - Date is always in UTC
  • This won't take daylight saving time into consideration (where there can be days which are only 23 hours long, for example)
  • Even within UTC, how many days are there in August 16th 11pm to August 18th 2am? It's only 27 hours, so does that mean one day? Or should it be three days because it covers three dates?
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    I thought java.util. Date was just a tiny wrapper around a time-millis representation, interpreted in the local (default) timezone. Printing out a Date gives me a local timezone representation. Am I confused here? – Adriaan Koster Aug 16 '10 at 09:49
39
Days d = Days.daysBetween(startDate, endDate);
int days = d.getDays();

https://www.joda.org/joda-time/faq.html#datediff

JodaStephen
  • 60,927
  • 15
  • 95
  • 117
Adriano Bacha
  • 1,114
  • 2
  • 13
  • 22
  • 2
    FYI, the [Joda-Time](http://www.joda.org/joda-time/) project is now in [maintenance mode](https://en.wikipedia.org/wiki/Maintenance_mode), with the team advising migration to the [java.time](http://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html) classes. – Basil Bourque Apr 16 '17 at 06:52
24

A slightly simpler alternative:

System.currentTimeMillis() - oldDate.getTime()

As for "nicer": well, what exactly do you need? The problem with representing time durations as a number of hours and days etc. is that it may lead to inaccuracies and wrong expectations due to the complexity of dates (e.g. days can have 23 or 25 hours due to daylight savings time).

Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
24

Since all the answers here are correct but use legacy java or 3rd party libs like joda or similar, I will just drop another way using new java.time classes in Java 8 and later. See Oracle Tutorial.

Use LocalDate and ChronoUnit:

LocalDate d1 = LocalDate.of(2017, 5, 1);
LocalDate d2 = LocalDate.of(2017, 5, 18);

long days = ChronoUnit.DAYS.between(d1, d2);
System.out.println( days );
Anatoly Shamov
  • 2,608
  • 1
  • 17
  • 27
ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97
23

Using millisecond approach can cause problems in some locales.

Lets take, for example, the difference between the two dates 03/24/2007 and 03/25/2007 should be 1 day;

However, using the millisecond route, you'll get 0 days, if you run this in the UK!

/** Manual Method - YIELDS INCORRECT RESULTS - DO NOT USE**/  
/* This method is used to find the no of days between the given dates */  
public long calculateDays(Date dateEarly, Date dateLater) {  
   return (dateLater.getTime() - dateEarly.getTime()) / (24 * 60 * 60 * 1000);  
} 

Better way to implement this is to use java.util.Calendar

/** Using Calendar - THE CORRECT WAY**/  
public static long daysBetween(Calendar startDate, Calendar endDate) {  
  Calendar date = (Calendar) startDate.clone();  
  long daysBetween = 0;  
  while (date.before(endDate)) {  
    date.add(Calendar.DAY_OF_MONTH, 1);  
    daysBetween++;  
  }  
  return daysBetween;  
}  
zasadnyy
  • 2,107
  • 2
  • 19
  • 26
  • 19
    Could you please credit the original author of this code and the third sentence, whose [blog entry is dated back to 2007](http://tripoverit.blogspot.com/2007_07_01_archive.html)? – wchargin Jan 15 '12 at 18:57
  • Isn't it a bit ineffective? – Gangnus Jan 11 '13 at 09:56
  • It does not work correctly. daysBetween(new GregorianCalendar(2014,03,01), new GregorianCalendar(2014,04,02))); returns 31, and it should return 32: http://www.timeanddate.com/date/durationresult.html?d1=01&m1=03&y1=2014&d2=02&m2=04&y2=2014 – marcolopes Apr 19 '14 at 04:51
  • 5
    @marcolopes -- You're wrong - because calendar months are zero based. I'm sure you're meaning march/april, but what you're testing is april/june which is 31. To be safe write it like -> new GregorianCalendar(2014, Calendar.MARCH, 1).... – Uncle Iroh Jun 25 '14 at 19:40
  • @UncleIroh, You're right! I missed that important fact (calendar months are zero based). I have to review this question all over again. – marcolopes Jun 26 '14 at 15:27
  • Warning: This method can return an incorrect result if the time fields are not zero and a daylight savings boundary is crossed. – Jool Aug 29 '16 at 12:43
23

There are many ways you can find the difference between dates & times. One of the simplest ways that I know of would be:

      Calendar calendar1 = Calendar.getInstance();
      Calendar calendar2 = Calendar.getInstance();
      calendar1.set(2012, 04, 02);
      calendar2.set(2012, 04, 04);
      long milsecs1= calendar1.getTimeInMillis();
      long milsecs2 = calendar2.getTimeInMillis();
      long diff = milsecs2 - milsecs1;
      long dsecs = diff / 1000;
      long dminutes = diff / (60 * 1000);
      long dhours = diff / (60 * 60 * 1000);
      long ddays = diff / (24 * 60 * 60 * 1000);

      System.out.println("Your Day Difference="+ddays);

The print statement is just an example - you can format it, the way you like.

Nabin
  • 11,216
  • 8
  • 63
  • 98
JDGuide
  • 6,239
  • 12
  • 46
  • 64
  • 5
    @ manoj kumar bardhan : welcome to stack overflow: As you see the question and answers are years old. Your answer should add more to the Question/Answer than the existing ones. – Jayan Apr 03 '12 at 08:03
  • 4
    What about the days that have 23 or 25 hours due to a DST transition? – Joni Jun 15 '12 at 06:23
10

Subtracting the dates in milliseconds works (as described in another post), but you have to use HOUR_OF_DAY and not HOUR when clearing the time parts of your dates:

public static final long MSPERDAY = 60 * 60 * 24 * 1000;
...
final Calendar dateStartCal = Calendar.getInstance();
dateStartCal.setTime(dateStart);
dateStartCal.set(Calendar.HOUR_OF_DAY, 0); // Crucial.
dateStartCal.set(Calendar.MINUTE, 0);
dateStartCal.set(Calendar.SECOND, 0);
dateStartCal.set(Calendar.MILLISECOND, 0);
final Calendar dateEndCal = Calendar.getInstance();
dateEndCal.setTime(dateEnd);
dateEndCal.set(Calendar.HOUR_OF_DAY, 0); // Crucial.
dateEndCal.set(Calendar.MINUTE, 0);
dateEndCal.set(Calendar.SECOND, 0);
dateEndCal.set(Calendar.MILLISECOND, 0);
final long dateDifferenceInDays = ( dateStartCal.getTimeInMillis()
                                  - dateEndCal.getTimeInMillis()
                                  ) / MSPERDAY;
if (dateDifferenceInDays > 15) {
    // Do something if difference > 15 days
}
Malcolm Boekhoff
  • 1,032
  • 11
  • 9
  • 1
    This the best method to determine the difference between two calendar dates, without going outside the standard libraries. Most of the other answers treat a day as an arbitrary 24-hour period. If leap seconds were ever to be subtracted rather than added, the final calculation could be off by one due to truncation, since the absolute difference could be slightly less than a whole number of multiples of MSPERDAY. – JulianSymes Jan 30 '14 at 16:13
9

If you don't want to use JodaTime or similar, the best solution is probably this:

final static long MILLIS_PER_DAY = 24 * 3600 * 1000;
long msDiff= date1.getTime() - date2.getTime();
long daysDiff = Math.round(msDiff / ((double)MILLIS_PER_DAY));

The number of ms per day is not always the same (because of daylight saving time and leap seconds), but it's very close, and at least deviations due to daylight saving time cancel out over longer periods. Therefore dividing and then rounding will give a correct result (at least as long as the local calendar used does not contain weird time jumps other than DST and leap seconds).

Note that this still assumes that date1 and date2 are set to the same time of day. For different times of day, you'd first have to define what "date difference" means, as pointed out by Jon Skeet.

sleske
  • 81,358
  • 34
  • 189
  • 227
  • The issue is in `date1.getTime()` vs `date2.getTime()`. So diffing 2016-03-03 to 2016-03-31 will compute 27 days while you would want 28 days. – malat Mar 29 '18 at 10:36
  • @malat: Sorry, I can't follow. I just tried it - diffing 2016-03-03 to 2016-03-31 with my code computes 28 days. If it computes something else in your example, consider asking that as a separate question. – sleske Mar 29 '18 at 11:45
  • Also, did you read my caveat? "this still assumes that date1 and date2 are set to the same time of day". Did you maybe use different times of day in your test? – sleske Mar 29 '18 at 11:46
  • Ah right ! I missed the trick with `Math.round()`, that seems safe in 'real world' calendars. Sorry for the noise. – malat Mar 29 '18 at 12:47
8

Take a look at Joda Time, which is an improved Date/Time API for Java and should work fine with Scala.

JodaStephen
  • 60,927
  • 15
  • 95
  • 117
Rob H
  • 14,502
  • 8
  • 42
  • 45
5

If you need a formatted return String like "2 Days 03h 42m 07s", try this:

public String fill2(int value)
{
    String ret = String.valueOf(value);

    if (ret.length() < 2)
        ret = "0" + ret;            
    return ret;
}

public String get_duration(Date date1, Date date2)
{                   
    TimeUnit timeUnit = TimeUnit.SECONDS;

    long diffInMilli = date2.getTime() - date1.getTime();
    long s = timeUnit.convert(diffInMilli, TimeUnit.MILLISECONDS);

    long days = s / (24 * 60 * 60);
    long rest = s - (days * 24 * 60 * 60);
    long hrs = rest / (60 * 60);
    long rest1 = rest - (hrs * 60 * 60);
    long min = rest1 / 60;      
    long sec = s % 60;

    String dates = "";
    if (days > 0) dates = days + " Days ";

    dates += fill2((int) hrs) + "h ";
    dates += fill2((int) min) + "m ";
    dates += fill2((int) sec) + "s ";

    return dates;
}
Ingo
  • 5,239
  • 1
  • 30
  • 24
  • 2
    Whoa, why roll your own when [Joda-Time](http://www.joda.org/joda-time/) provides the [Period](http://www.joda.org/joda-time/apidocs/org/joda/time/Period.html) class already written and debugged? – Basil Bourque Mar 23 '14 at 07:31
  • 8
    Why should I download a Library with a compressed FileSize of 4.1 MB and add it to my Project, when I only need 32 Lines of code??? – Ingo Mar 30 '14 at 00:39
  • 1
    Because Joda-Time is like potato chips: you can't eat just one. You'll be using Joda-Time all over the place. And because Joda-Time is well-tested and well-worn code. And because Joda-Time parses and generates standard [ISO 8601 Duration](http://en.wikipedia.org/wiki/ISO_8601#Durations) strings which may be handy for serializing or reporting these values. And because Joda-Time includes formatters to print localized representations of these values. – Basil Bourque Dec 19 '14 at 18:31
  • Not all your code is tested. `std` above is undefined. – Basil Bourque Dec 21 '14 at 03:36
  • @Basil Bourque: Thx for the hint. I have corected the source. This error came from translation to english. – Ingo Dec 21 '14 at 03:51
  • I just did some testing of your code (after changing `std` to `hrs`), comparing to Joda-Time. Went well, your code agreed with Joda-Time in each of my test cases. But I still recommend against rolling your own date-time library (as too risky, not a good use of your time, many desirable features in Joda-Time such as easy handling of time zones). – Basil Bourque Dec 21 '14 at 04:01
  • @Basil Bourque; Thx for testing. I use my "get_duration function in many cases without any Problems also in other languages like c++, c#, delphi etc. But if you like Joda Time, use it :-) – Ingo Dec 21 '14 at 04:09
5

Note: startDate and endDates are -> java.util.Date

import org.joda.time.Duration;
import org.joda.time.Interval;
// Use .getTime() unless it is a joda DateTime object
Interval interval = new Interval(startDate.getTime(), endDate.getTime());
Duration period = interval.toDuration();
//gives the number of days elapsed between start and end date.
period.getStandardDays();

Similar to days, you can also get hours, minutes and seconds

period.getStandardHours();
period.getStandardMinutes();
period.getStandardSeconds();
TiyebM
  • 2,684
  • 3
  • 40
  • 66
Shravan Ramamurthy
  • 3,896
  • 5
  • 30
  • 44
5
int daysDiff = (date1.getTime() - date2.getTime()) / MILLIS_PER_DAY;
Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • 5
    -1 That's wrong unless the Date instances were derived from UTC times. See Jon Skeet's answer. – sleske Aug 30 '10 at 13:25
  • 5
    @sleske you are not right. He has already lost the timezone information by using `Date`, so this comparison is the best that can be achieved given the circumstances. – Bozho Aug 30 '10 at 13:35
  • 1
    OK, guess we're both right. It's true that it depends on where the Date instance comes from. Still, it's such a common mistake that it should be mentioned. – sleske Aug 30 '10 at 13:57
  • When I use your solution, it says: Type mismatch: cannot convert from long to int. I think you should also add casting or am I missing something? – Ad Infinitum Oct 04 '17 at 07:23
5

After wading through all the other answers, to keep the Java 7 Date type but be more precise/standard with the Java 8 diff approach,

public static long daysBetweenDates(Date d1, Date d2) {
    Instant instant1 = d1.toInstant();
    Instant instant2 = d2.toInstant();
    long diff = ChronoUnit.DAYS.between(instant1, instant2);
    return diff;
}
gene b.
  • 10,512
  • 21
  • 115
  • 227
5

Let me show difference between Joda Interval and Days:

DateTime start = new DateTime(2012, 2, 6, 10, 44, 51, 0);
DateTime end = new DateTime(2012, 2, 6, 11, 39, 47, 1);
Interval interval = new Interval(start, end);
Period period = interval.toPeriod();
System.out.println(period.getYears() + " years, " + period.getMonths() + " months, " + period.getWeeks() + " weeks, " + period.getDays() + " days");
System.out.println(period.getHours() + " hours, " + period.getMinutes() + " minutes, " + period.getSeconds() + " seconds ");
//Result is:
//0 years, 0 months, *1 weeks, 1 days*
//0 hours, 54 minutes, 56 seconds 

//Period can set PeriodType,such as PeriodType.yearMonthDay(),PeriodType.yearDayTime()...
Period p = new Period(start, end, PeriodType.yearMonthDayTime());
System.out.println(p.getYears() + " years, " + p.getMonths() + " months, " + p.getWeeks() + " weeks, " + p.getDays() + "days");
System.out.println(p.getHours() + " hours, " + p.getMinutes() + " minutes, " + p.getSeconds() + " seconds ");
//Result is:
//0 years, 0 months, *0 weeks, 8 days*
//0 hours, 54 minutes, 56 seconds 
user674158
  • 221
  • 2
  • 6
4

Following code can give you the desired output:

String startDate = "Jan 01 2015";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM dd yyyy");
LocalDate date = LocalDate.parse(startDate, formatter);

String currentDate = "Feb 11 2015";
LocalDate date1 = LocalDate.parse(currentDate, formatter);

System.out.println(date1.toEpochDay() - date.toEpochDay());
Jared Burrows
  • 54,294
  • 25
  • 151
  • 185
  • 3
    Can you explain exactly what your code does? The question seems to be asking about a time delta and, on first glance, your code would seem to return a day delta? – GHC Feb 19 '15 at 07:57
4
public static String getDifferenceBtwTime(Date dateTime) {

    long timeDifferenceMilliseconds = new Date().getTime() - dateTime.getTime();
    long diffSeconds = timeDifferenceMilliseconds / 1000;
    long diffMinutes = timeDifferenceMilliseconds / (60 * 1000);
    long diffHours = timeDifferenceMilliseconds / (60 * 60 * 1000);
    long diffDays = timeDifferenceMilliseconds / (60 * 60 * 1000 * 24);
    long diffWeeks = timeDifferenceMilliseconds / (60 * 60 * 1000 * 24 * 7);
    long diffMonths = (long) (timeDifferenceMilliseconds / (60 * 60 * 1000 * 24 * 30.41666666));
    long diffYears = (long)(timeDifferenceMilliseconds / (1000 * 60 * 60 * 24 * 365));

    if (diffSeconds < 1) {
        return "one sec ago";
    } else if (diffMinutes < 1) {
        return diffSeconds + " seconds ago";
    } else if (diffHours < 1) {
        return diffMinutes + " minutes ago";
    } else if (diffDays < 1) {
        return diffHours + " hours ago";
    } else if (diffWeeks < 1) {
        return diffDays + " days ago";
    } else if (diffMonths < 1) {
        return diffWeeks + " weeks ago";
    } else if (diffYears < 12) {
        return diffMonths + " months ago";
    } else {
        return diffYears + " years ago";
    }
}   
Parth Solanki
  • 3,268
  • 2
  • 22
  • 41
4

Check example here http://www.roseindia.net/java/beginners/DateDifferent.shtml This example give you difference in days, hours, minutes, secs and milli sec's :).

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

public class DateDifferent {
    public static void main(String[] args) {
        Date date1 = new Date(2009, 01, 10);
        Date date2 = new Date(2009, 07, 01);
        Calendar calendar1 = Calendar.getInstance();
        Calendar calendar2 = Calendar.getInstance();
        calendar1.setTime(date1);
        calendar2.setTime(date2);
        long milliseconds1 = calendar1.getTimeInMillis();
        long milliseconds2 = calendar2.getTimeInMillis();
        long diff = milliseconds2 - milliseconds1;
        long diffSeconds = diff / 1000;
        long diffMinutes = diff / (60 * 1000);
        long diffHours = diff / (60 * 60 * 1000);
        long diffDays = diff / (24 * 60 * 60 * 1000);
        System.out.println("\nThe Date Different Example");
        System.out.println("Time in milliseconds: " + diff + " milliseconds.");
        System.out.println("Time in seconds: " + diffSeconds + " seconds.");
        System.out.println("Time in minutes: " + diffMinutes + " minutes.");
        System.out.println("Time in hours: " + diffHours + " hours.");
        System.out.println("Time in days: " + diffDays + " days.");
    }
}
YoK
  • 14,329
  • 4
  • 49
  • 67
  • 3
    -1 That's wrong unless the Date instances were derived from UTC times. See Jon Skeet's answer. – sleske Aug 30 '10 at 13:25
4

Use GMT time zone to get an instance of the Calendar, set the time using the set method of Calendar class. The GMT timezone has 0 offset (not really important) and daylight saving time flag set to false.

    final Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));

    cal.set(Calendar.YEAR, 2011);
    cal.set(Calendar.MONTH, 9);
    cal.set(Calendar.DAY_OF_MONTH, 29);
    cal.set(Calendar.HOUR, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    final Date startDate = cal.getTime();

    cal.set(Calendar.YEAR, 2011);
    cal.set(Calendar.MONTH, 12);
    cal.set(Calendar.DAY_OF_MONTH, 21);
    cal.set(Calendar.HOUR, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    final Date endDate = cal.getTime();

    System.out.println((endDate.getTime() - startDate.getTime()) % (1000l * 60l * 60l * 24l));
Michal
  • 41
  • 1
  • Don't forget to zero the millisecond part else it is a good answer in context of old classes `java.util.Date` etc. Using the hack to set the timezone to GMT makes the code insensitive for daylight saving effects. – Meno Hochschild Dec 09 '16 at 17:24
3

Best thing to do is

(Date1-Date2)/86 400 000 

That number is the number of milliseconds in a day.

One date-other date gives you difference in milliseconds.

Collect the answer in a double variable.

benka
  • 4,732
  • 35
  • 47
  • 58
Revanth Kumar
  • 809
  • 12
  • 18
  • Yes why not? I don't understand the point of the question in some ways: OP has a difference in ms... and there are a certain number of ms in a day (OK with certain astronomical adjustments once in a blue moon, but the OP doesn't say that it must be as precise as astronomers need it...) – mike rodent Feb 25 '17 at 19:50
3

Here's a correct Java 7 solution in O(1) without any dependencies.

public static int countDaysBetween(Date date1, Date date2) {

    Calendar c1 = removeTime(from(date1));
    Calendar c2 = removeTime(from(date2));

    if (c1.get(YEAR) == c2.get(YEAR)) {

        return Math.abs(c1.get(DAY_OF_YEAR) - c2.get(DAY_OF_YEAR)) + 1;
    }
    // ensure c1 <= c2
    if (c1.get(YEAR) > c2.get(YEAR)) {
        Calendar c = c1;
        c1 = c2;
        c2 = c;
    }
    int y1 = c1.get(YEAR);
    int y2 = c2.get(YEAR);
    int d1 = c1.get(DAY_OF_YEAR);
    int d2 = c2.get(DAY_OF_YEAR);

    return d2 + ((y2 - y1) * 365) - d1 + countLeapYearsBetween(y1, y2) + 1;
}

private static int countLeapYearsBetween(int y1, int y2) {

    if (y1 < 1 || y2 < 1) {
        throw new IllegalArgumentException("Year must be > 0.");
    }
    // ensure y1 <= y2
    if (y1 > y2) {
        int i = y1;
        y1 = y2;
        y2 = i;
    }

    int diff = 0;

    int firstDivisibleBy4 = y1;
    if (firstDivisibleBy4 % 4 != 0) {
        firstDivisibleBy4 += 4 - (y1 % 4);
    }
    diff = y2 - firstDivisibleBy4 - 1;
    int divisibleBy4 = diff < 0 ? 0 : diff / 4 + 1;

    int firstDivisibleBy100 = y1;
    if (firstDivisibleBy100 % 100 != 0) {
        firstDivisibleBy100 += 100 - (firstDivisibleBy100 % 100);
    }
    diff = y2 - firstDivisibleBy100 - 1;
    int divisibleBy100 = diff < 0 ? 0 : diff / 100 + 1;

    int firstDivisibleBy400 = y1;
    if (firstDivisibleBy400 % 400 != 0) {
        firstDivisibleBy400 += 400 - (y1 % 400);
    }
    diff = y2 - firstDivisibleBy400 - 1;
    int divisibleBy400 = diff < 0 ? 0 : diff / 400 + 1;

    return divisibleBy4 - divisibleBy100 + divisibleBy400;
}


public static Calendar from(Date date) {

    Calendar c = Calendar.getInstance();
    c.setTime(date);

    return c;
}


public static Calendar removeTime(Calendar c) {

    c.set(HOUR_OF_DAY, 0);
    c.set(MINUTE, 0);
    c.set(SECOND, 0);
    c.set(MILLISECOND, 0);

    return c;
}
suxumuxu
  • 121
  • 1
  • 1
  • 10
2

Not using the standard API, no. You can roll your own doing something like this:

class Duration {
    private final TimeUnit unit;
    private final long length;
    // ...
}

Or you can use Joda:

DateTime a = ..., b = ...;
Duration d = new Duration(a, b);
gustafc
  • 28,465
  • 7
  • 73
  • 99
2

That's probably the most straightforward way to do it - perhaps it's because I've been coding in Java (with its admittedly clunky date and time libraries) for a while now, but that code looks "simple and nice" to me!

Are you happy with the result being returned in milliseconds, or is part of your question that you would prefer to have it returned in some alternative format?

Andrzej Doyle
  • 102,507
  • 33
  • 189
  • 228
2

Just to answer the initial question:

Put the following code in a Function like Long getAge(){}

Date dahora = new Date();
long MillisToYearsByDiv = 1000l *60l * 60l * 24l * 365l;
long javaOffsetInMillis = 1990l * MillisToYearsByDiv;
long realNowInMillis = dahora.getTime() + javaOffsetInMillis;
long realBirthDayInMillis = this.getFechaNac().getTime() + javaOffsetInMillis;
long ageInMillis = realNowInMillis - realBirthDayInMillis;

return ageInMillis / MillisToYearsByDiv;

The most important here is to work with long numbers when multiplying and dividing. And of course, the offset that Java applies in its calculus of Dates.

:)

2

Since the question is tagged with Scala,

import scala.concurrent.duration._
val diff = (System.currentTimeMillis() - oldDate.getTime).milliseconds
val diffSeconds = diff.toSeconds
val diffMinutes = diff.toMinutes
val diffHours = diff.toHours
val diffDays = diff.toDays
VasiliNovikov
  • 9,681
  • 4
  • 44
  • 62
2

If you want to fix the issue for date ranges that cross daylight savings time boundary (e.g. one date in summer time and the other one in winter time), you can use this to get the difference in days:

public static long calculateDifferenceInDays(Date start, Date end, Locale locale) {
    Calendar cal = Calendar.getInstance(locale);

    cal.setTime(start);
    cal.set(Calendar.HOUR_OF_DAY, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);
    long startTime = cal.getTimeInMillis();

    cal.setTime(end);
    cal.set(Calendar.HOUR_OF_DAY, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);
    long endTime = cal.getTimeInMillis();

    // calculate the offset if one of the dates is in summer time and the other one in winter time
    TimeZone timezone = cal.getTimeZone();
    int offsetStart = timezone.getOffset(startTime);
    int offsetEnd = timezone.getOffset(endTime);
    int offset = offsetEnd - offsetStart;

    return TimeUnit.MILLISECONDS.toDays(endTime - startTime + offset);
}
Fabi
  • 153
  • 1
  • 6
1

try this:

int epoch = (int) (new java.text.SimpleDateFormat("MM/dd/yyyy HH:mm:ss").parse("01/01/1970  00:00:00").getTime() / 1000);

you can edit the string in the parse() methods param.

sabbibJAVA
  • 1,068
  • 1
  • 11
  • 17
1

Since you are using Scala, there is a very good Scala library Lamma. With Lamma you can minus date directly with - operator

scala> Date(2015, 5, 5) - 2     // minus days by int
res1: io.lamma.Date = Date(2015,5,3)

scala> Date(2015, 5, 15) - Date(2015, 5, 8)   // minus two days => difference between two days
res2: Int = 7
Max
  • 2,065
  • 24
  • 20
1

Just use below method with two Date objects. If you want to pass current date, just pass new Date() as a second parameter as it is initialised with current time.

public String getDateDiffString(Date dateOne, Date dateTwo)
{
    long timeOne = dateOne.getTime();
    long timeTwo = dateTwo.getTime();
    long oneDay = 1000 * 60 * 60 * 24;
    long delta = (timeTwo - timeOne) / oneDay;

    if (delta > 0) {
        return "dateTwo is " + delta + " days after dateOne";
    }
    else {
        delta *= -1;
        return "dateTwo is " + delta + " days before dateOne";
     }
}

Also, apart from from number of days, if, you want other parameter difference too, use below snippet,

int year = delta / 365;
int rest = delta % 365;
int month = rest / 30;
rest = rest % 30;
int weeks = rest / 7;
int days = rest % 7;

P.S Code is entirely taken from an SO answer.

Shubham A.
  • 2,446
  • 4
  • 36
  • 68
  • Glad to see you participating in StackOverflow. Please add some discussion along with your posted code example. Explain how your code works, how your Answer differs from the others, point out any tricky concepts, link to doc, and so on. StackOverflow is meant to be more than a code snippet library. – Basil Bourque Oct 05 '15 at 16:30
1

After having read many answers and comments to this question, I was left with the impression that one either has to use the Joda time or else take into account some peculiarities with the daylight saving time etc. Since I didn't want to do either of these, I ended up writing a few lines of code to calculate the difference between two dates without using any date or time related Java classes.

In the code below the numbers of year, month and day are the same as in real life. For example in December 24th 2015, the year = 2015, the month = 12 and the day = 24.

I want to share this code in case someone else wants to use it. There are 3 methods: 1) A method to find out whether a given year is a leap year 2) A method to calculate the number of a given day in relation to January 1st of a given year 3) A method to calculate the number of days between any two dates using the method 2 (number of the end date minus number of the start date).

Here are the methods:

1)

public static boolean isLeapYear (int year) {
    //Every 4. year is a leap year, except if the year is divisible by 100 and not by 400
    //For example 1900 is not a leap year but 2000 is

    boolean result = false;

    if (year % 4 == 0) {
        result = true;
    }
    if (year % 100 == 0) {
        result = false;
    }
    if (year % 400 == 0) {
        result = true;
    }

    return result;

}

2)

public static int daysGoneSince (int yearZero, int year, int month, int day) {
    //Calculates the day number of the given date; day 1 = January 1st in the yearZero

    //Validate the input
    if (year < yearZero || month < 1 || month > 12 || day < 1 || day > 31) {
        //Throw an exception
        throw new IllegalArgumentException("Too many or too few days in month or months in year or the year is smaller than year zero");
    }
    else if (month == 4 || month == 6 || month == 9 || month == 11) {//Months with 30 days
        if (day == 31) {
            //Throw an exception
            throw new IllegalArgumentException("Too many days in month");
        }
    }
    else if (month == 2) {//February 28 or 29
        if (isLeapYear(year)) {
            if (day > 29) {
                //Throw an exception
                throw new IllegalArgumentException("Too many days in month");
            }
        }
        else if (day > 28) {
            //Throw an exception
            throw new IllegalArgumentException("Too many days in month");
        }
    }

    //Start counting days
    int days = 0;

    //Days in the target month until the target day
    days = days + day;

    //Days in the earlier months in the target year
    for (int i = 1; i < month; i++) {
        switch (i) {
            case 1: case 3: case 5:
            case 7: case 8: case 10:
            case 12:
                days = days + 31;
                break;
            case 2:
                days = days + 28;
                if (isLeapYear(year)) {
                    days = days + 1;
                }
                break;
            case 4: case 6: case 9: case 11:
                days = days + 30;
                break;
        }
    }

    //Days in the earlier years
    for (int i = yearZero; i < year; i++) {
        days = days + 365;
        if (isLeapYear(i)) {
            days = days + 1;
        }
    }

    return days;

}

3)

public static int dateDiff (int startYear, int startMonth, int startDay, int endYear, int endMonth, int endDay) {

    int yearZero;

    //daysGoneSince presupposes that the first argument be smaller or equal to the second argument
    if (10000 * startYear + 100 * startMonth + startDay > 10000 * endYear + 100 * endMonth + endDay) {//If the end date is earlier than the start date
        yearZero = endYear;
    }
    else {
        yearZero = startYear;
    }

    return daysGoneSince(yearZero, endYear, endMonth, endDay) - daysGoneSince(yearZero, startYear, startMonth, startDay);

}
1

Earlier versions of Java you can try.

 public static String daysBetween(Date createdDate, Date expiryDate) {

        Calendar createdDateCal = Calendar.getInstance();
        createdDateCal.clear();
        createdDateCal.setTime(createdDate);

        Calendar expiryDateCal = Calendar.getInstance();
        expiryDateCal.clear();
        expiryDateCal.setTime(expiryDate);


        long daysBetween = 0;
        while (createdDateCal.before(expiryDateCal)) {
            createdDateCal.add(Calendar.DAY_OF_MONTH, 1);
            daysBetween++;
        }
        return daysBetween+"";
    }
Kumar Abhishek
  • 3,004
  • 33
  • 29
0

@Michael Borgwardt's answer actually does not work correctly in Android. Rounding errors exist. Example 19th to 21st May says 1 day because it casts 1.99 to 1. Use round before casting to int.

Fix

int diffInDays = (int)Math.round(( (newerDate.getTime() - olderDate.getTime()) 
                 / (1000 * 60 * 60 * 24) ))

Note that this works with UTC dates, so the difference may be a day off if you look at local dates. And getting it to work correctly with local dates requires a completely different approach due to daylight savings time.

Pratik Mandrekar
  • 9,362
  • 4
  • 45
  • 65
  • As long as both timestamps are in the same time zone, then the difference between the dates will be the same whether adjusted for the local time zone from UTC or not (the adjustments subtract out). There is a possibility for a DST correction to the result, but if you begin with the assumption that a day is 86400 seconds, it really doesn't matter. – scottb May 16 '13 at 05:03
  • That's not the point of the answer. Michael Brogwardt's answer results in the wrong result unless you round it up and cast to int in Android's Java SDK. – Pratik Mandrekar May 16 '13 at 11:54
0
public static void main(String[] args) {

    String dateStart = "01/14/2012 09:29:58";
    String dateStop = "01/14/2012 10:31:48";

    SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");

    Date d1 = null;
    Date d2 = null;

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

        DateTime date11 = new DateTime(d1);
        DateTime date22 = new DateTime(d2);
        int days = Days.daysBetween(date11.withTimeAtStartOfDay(), date22.withTimeAtStartOfDay()).getDays();
        int hours = Hours.hoursBetween(date11, date22).getHours() % 24;
        int minutes = Minutes.minutesBetween(date11, date22).getMinutes() % 60;
        int seconds = Seconds.secondsBetween(date11, date22).getSeconds() % 60;
        if (hours > 0 || minutes > 0 || seconds > 0) {
            days = days + 1;
        }

        System.out.println(days);

    } catch (Exception e) {
        e.printStackTrace();
    }

}

This will give date diff for the same day as well

spysr
  • 1
  • 3
  • 1
    Can you add some explanation of your answer’s added value? Seems redundant with [this answer](http://stackoverflow.com/a/3491720/642706) and [this answer](http://stackoverflow.com/a/19172605/642706). And other answers seem better, such as making use of the [`TimeUnit`](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/TimeUnit.html) Enum utility class. – Basil Bourque Nov 23 '14 at 00:02
  • Actually problem in each of those implementation is it does count 0 for same day datetime... but with this you can get same day diff as 1 , moreover it depends @BasilBourque – spysr Dec 10 '14 at 14:07
0

I liked the TimeUnit-based approach until I found out that it only covers the trivial cases where the number of how many units of one timeunit are in the next higher unit is fixed. This breaks apart when you want to know how many months, year, etc are in between.

here is a counting approach, not as efficient as some others, but it seems to work for me and takes into account DST, too.

public static String getOffsetAsString( Calendar cNow, Calendar cThen) {
    Calendar cBefore;
    Calendar cAfter;
    if ( cNow.getTimeInMillis() < cThen.getTimeInMillis()) {
        cBefore = ( Calendar) cNow.clone();
        cAfter = cThen;
    } else {
        cBefore = ( Calendar) cThen.clone();
        cAfter = cNow;
    }
    // compute diff
    Map<Integer, Long> diffMap = new HashMap<Integer, Long>();
    int[] calFields = { Calendar.YEAR, Calendar.MONTH, Calendar.DAY_OF_MONTH, Calendar.HOUR_OF_DAY, Calendar.MINUTE, Calendar.SECOND, Calendar.MILLISECOND};
    for ( int i = 0; i < calFields.length; i++) {
        int field = calFields[ i];
        long    d = computeDist( cAfter, cBefore, field);
        diffMap.put( field, d);
    }
    final String result = String.format( "%dY %02dM %dT %02d:%02d:%02d.%03d",
            diffMap.get( Calendar.YEAR), diffMap.get( Calendar.MONTH), diffMap.get( Calendar.DAY_OF_MONTH), diffMap.get( Calendar.HOUR_OF_DAY), diffMap.get( Calendar.MINUTE), diffMap.get( Calendar.SECOND), diffMap.get( Calendar.MILLISECOND));
    return result;
}

private static int computeDist( Calendar cAfter, Calendar cBefore, int field) {
    cBefore.setLenient( true);
    System.out.print( "D " + new Date( cBefore.getTimeInMillis()) + " --- " + new Date( cAfter.getTimeInMillis()) + ": ");
    int count = 0;
    if ( cAfter.getTimeInMillis() > cBefore.getTimeInMillis()) {
        int fVal = cBefore.get( field);
        while ( cAfter.getTimeInMillis() >= cBefore.getTimeInMillis()) {
            count++;
            fVal = cBefore.get( field);
            cBefore.set( field, fVal + 1);
            System.out.print( count + "/"  + ( fVal + 1) + ": " + new Date( cBefore.getTimeInMillis()) + " ] ");
        }
        int result = count - 1;
        cBefore.set( field, fVal);
        System.out.println( "" + result + " at: " + field + " cb = " + new Date( cBefore.getTimeInMillis()));
        return result;
    }
    return 0;
}
Ralf H
  • 1,392
  • 1
  • 9
  • 17
0

This is another sample. Which basically works for user-defined pattern.

   public static LinkedHashMap<String, Object> checkDateDiff(DateTimeFormatter dtfObj, String startDate, String endDate)
   {
          Map<String, Object> dateDiffMap = new HashMap<String, Object>();
          DateTime start = DateTime.parse(startDate,dtfObj);
          DateTime end = DateTime.parse(endDate,dtfObj);
          Interval interval = new Interval(start, end);
          Period period = interval.toPeriod();

          dateDiffMap.put("ISO-8601_PERIOD_FORMAT", period);
          dateDiffMap.put("YEAR", period.getYears());
          dateDiffMap.put("MONTH", period.getMonths());
          dateDiffMap.put("WEEK", period.getWeeks());
          dateDiffMap.put("DAY", period.getWeeks());             
          dateDiffMap.put("HOUR", period.getHours());
          dateDiffMap.put("MINUTE", period.getMinutes());
          dateDiffMap.put("SECOND", period.getSeconds());

          return dateDiffMap;        
   }
The N..
  • 70
  • 1
  • 5
  • Thanks for trying to contribute to StackOverflow. I suggest you add some discussion or explanation. StackOverflow is meant to more than a snippet library. So you should explain (a) how your code works, and (b) how it adds value beyond the many other Answers already posted on this Question. Also, this code is not complete, with variables such as `dtfObj` that have no declaration nor assignment. Lastly, as an aside, I offer this tip: You can use the more general `Map` interface on the left of your first line rather than `LinkedHashMap`. That is one of the points/benefits to polymorphism. – Basil Bourque Jan 29 '15 at 07:14
  • @BasilBourque : Hi, I have made expected changes and sure will try to add more for explanation. – The N.. Feb 12 '15 at 06:12
0

There is an easy way to do this in java

//create an utility method

public long getDaysBetweenDates(Date d1, Date d2){
return TimeUnit.MILLISECONDS.toDays(d1.getTime() - d2.getTime());
}

This method will return the number of days between the 2 dates. Either you can use the default java date format or can easily convert from any date format.

Vishal Kumar
  • 4,419
  • 1
  • 25
  • 31
  • 3
    This assumes a constant number of milliseconds in a day. This is not always true. – pr1001 Oct 29 '15 at 16:40
  • Yes, as @pr1001 mentioned. What if you measure today at 22:00 and day after tomorrow at 00:00? You will have 1.08 which will result in 1 day difference, but in fact suppose to be 2! – M22 Nov 27 '21 at 23:03
0

Just call getTime on each, take the difference, and divide by the number of milliseconds in a day.

pauljwilliams
  • 19,079
  • 3
  • 51
  • 79
  • 5
    -1 That's wrong unless the Date instances were derived from UTC times. See Jon Skeet's answer. – sleske Aug 30 '10 at 13:24
0

Another pure Java variation:

public boolean isWithin30Days(Calendar queryCalendar) {

    // 1. Take the date you are checking, and roll it back N days
    Calendar queryCalMinus30Days = Calendar.getInstance();
    queryCalMinus30Days.setTime(queryCalendar.getTime());
    queryCalMinus30Days.add(Calendar.DATE, -30); // subtract 30 days from the calendar

    // 2. Get respective milliseconds for the two Calendars: now & queryCal minus N days 
    long nowL = Calendar.getInstance().getTimeInMillis();
    long queryCalMinus30DaysL = queryCalMinus30Days.getTimeInMillis();

    // 3. if nowL is still less than the queryCalMinus30DaysL, it means queryCalendar is more than 30 days into future
    boolean isWithin30Days = nowL >= queryCalMinus30DaysL;

    return isWithin30Days;
}

thanks to starter code here: https://stackoverflow.com/a/30207726/2162226

Community
  • 1
  • 1
Gene Bo
  • 11,284
  • 8
  • 90
  • 137
0

The following is one solution, as there are numerous ways we can achieve this:

  import java.util.*; 
   int syear = 2000;
   int eyear = 2000;
   int smonth = 2;//Feb
   int emonth = 3;//Mar
   int sday = 27;
   int eday = 1;
   Date startDate = new Date(syear-1900,smonth-1,sday);
   Date endDate = new Date(eyear-1900,emonth-1,eday);
   int difInDays = (int) ((endDate.getTime() - startDate.getTime())/(1000*60*60*24));
kundan bora
  • 3,821
  • 2
  • 20
  • 29
-1

Since dates can contain hours and minutes, final result will be rounded down, which will result in incorrect value. For example, you calculate difference between today at 22:00 p.m and day after tomorrow 00:00 a.m, so the final result will be 1, because in reality it was 1.08 or smth difference, then it gets rounded down when calling TimeUnit.MILLISECONDS.toDays(..). That's why you need to take that in account, so in my solution I subtract the remainder of milliseconds from milliseconds in a day. Additionally, if you want to count the end date, you need to +1 it.

import java.util.Date;
import java.util.concurrent.TimeUnit;

public static long getDaysBetween(Date date1, Date date2, boolean includeEndDate) {
        long millisInDay = 60 * 60 * 24 * 1000;
        long difference = Math.abs(date1.getTime() - date2.getTime());
        long add = millisInDay - (difference % millisInDay);//is used to calculate true number of days, because by default hours, minutes are also counted

        return TimeUnit.MILLISECONDS.toDays(difference + add) + (includeEndDate ? 1 : 0);
    }

Tests:

Date date1 = new Date(121, Calendar.NOVEMBER, 27); //2021 Nov 27
Date date2 = new Date(121, Calendar.DECEMBER, 29); //2021 Dec 29
System.out.println( getDaysBetween(date1, date2, false) ); //32 days difference
System.out.println( getDaysBetween(date1, date2, true) ); //33 days difference
M22
  • 543
  • 5
  • 10
  • It’s not quite correct since a day is not always 24 hours. And no one should use `Date` and `Calendar` anymore. – Ole V.V. Nov 28 '21 at 02:48
  • @OleV.V. how many hours in a day? – M22 Nov 28 '21 at 05:38
  • That depends. Which day in which time zone? Most often 24. Sometimes 23 or 25 or not a whole number. In Kristianstad October 31 this year was 25 hours long, for example. – Ole V.V. Nov 28 '21 at 06:00
  • I only notice now that you are using the 3-arg `Date` constructor. Argh! It’s been deprecated for close to 25 years because it works unreliably across time zones. **Don’t!** In any case I agree with you that your code *should* give 32 and 33 days. When I run it, I get 33 and 34. Your code does not work the way you claim it does. – Ole V.V. Nov 28 '21 at 17:01
-1

This will perfectly works with joda api

 import java.util.Calendar;
    import java.util.Date;
    import java.util.GregorianCalendar;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import org.joda.time.DateTime;
    import org.joda.time.Months;
    import org.joda.time.Weeks;
    import org.joda.time.Years;
    import java.util.LinkedHashMap;
    
    public Map<String,Integer> Datedifference(String fromDate,String toDate) throws ParseException {    
                Map<String,Integer> dateUtilMap = new LinkedHashMap<String, Integer>();
                Date date1=new SimpleDateFormat("dd-MM-yyyy").parse(fromDate);  
                Date date2=new SimpleDateFormat("dd-MM-yyyy").parse(toDate);  
                Calendar fromDay = new GregorianCalendar();
                fromDay.setTime(date1);
                Calendar toDay = new GregorianCalendar();
                toDay.setTime(date2);
                
                int days = (int) (1+(toDay.getTimeInMillis() -fromDay.getTimeInMillis()) / 1000 / 60 / 60 / 24);
                
                if(days >1) {
                    
                DateTime dateTime1 = new DateTime(fromDay);
                DateTime dateTime2 = new DateTime(toDay);
                
                int weeks = Weeks.weeksBetween(dateTime1.dayOfWeek().withMinimumValue().minusDays(1), 
                        dateTime2.dayOfWeek().withMaximumValue().plusDays(1)).getWeeks();
                
                int months = Months.monthsBetween(dateTime1.dayOfMonth().withMinimumValue().minusDays(1),
                        dateTime2.dayOfMonth().withMaximumValue().plusDays(1)).getMonths();
                
                int years =1+Years.yearsBetween(dateTime1, dateTime2).getYears();
                
                dateUtilMap.put("days", days);
                dateUtilMap.put("weeks", weeks);
                dateUtilMap.put("months", months);
                dateUtilMap.put("years", years);
                System.out.println(dateUtilMap);
                return dateUtilMap;        
                } else {
                    System.out.println("From Date Must be samller than to Date");
                 return null;
                } 
        }
  • 1
    Thank you for wanting to contribute. This code is strongly discouraged. The Joda-Time project is in maintenance, but a lot worse, you are also using the notoriously troublesome `SimpleDateFormat` and the poorly designed and cumbersome `Date` and `Calendar` classes. Your code is much longer, much more complex and less readable than it needed to be. And not properly indented. And you are answering a different question. The question was about two `Date` objects (not two strings). – Ole V.V. May 10 '23 at 10:39
  • `Datedifference("10-05-2023", "11-05-2023")` (from today till tomorrow) gave `{days=2, weeks=1, months=1, years=1}`. I was a bit surprised, but OK, I guess everyone has got their own definition of "perfect". Then I tried `Datedifference("26-03-2023", "27-03-2023")` and got -- `null`??! What goes? I should say that your code is not correct by any definition of the word. – Ole V.V. May 10 '23 at 12:47
-3

If you have d1 and d2 as your dates, the best solution is probably the following:

int days1 = d1.getTime()/(60*60*24*1000);//find the number of days since the epoch.
int days2 = d2.getTime()/(60*60*24*1000);

then just say

days2-days1

or whatever

codersarepeople
  • 1,971
  • 3
  • 20
  • 25
  • 3
    -1 That's wrong unless the Date instances were derived from UTC times. See Jon Skeet's answer. – sleske Aug 30 '10 at 13:26
  • This is incorrect. Internally, Date instances are a thin wrapper around a long that represents POSIX Epoch Time. This is only defined for UTC. Therefore, the value returned by dateObject.getTime() is always in UTC. – scottb May 16 '13 at 04:59