Find total hours between two Dates - java

I have two Date objects and I need to get the time difference so I can determine the total hours between them. They happen to be from the same day. The result I would like would have the hours and minutes.
When I use .toString() on my Date object I get this: Fri Dec 18 08:08:10 CST 2009
I've tried the following:
long diff = (this.endDate.getTime() - this.startDate.getTime()) / (60 * 60 * 1000);
But this only gives me hours, not the minutes.
I know this is a simple problem, but I can't figure it out atm.
Edits:
Final solution for those interested. Thanks to Michael Brewer-Davis
Period p = new Period(this.startDate, this.endDate);
long hours = p.getHours();
long minutes = p.getMinutes();
String format = String.format("%%0%dd", 2);
return Long.toString(hours) + ":" + String.format(format, minutes);

This should work.
long secs = (this.endDate.getTime() - this.startDate.getTime()) / 1000;
int hours = secs / 3600;
secs = secs % 3600;
int mins = secs / 60;
secs = secs % 60;

Here's how it works with Joda time:
DateTime startTime, endTime;
Period p = new Period(startTime, endTime);
int hours = p.getHours();
int minutes = p.getMinutes();
You could format with Joda's formatters, e.g., PeriodFormat, but I'd suggest using Java's. See this question for more details.
EDIT: be careful using this method to check hours between. This function don't respect days between. It get just hours between two times. 2022-07-20 11.00 and 2022-07-21 12.00 will return 1 hour, not 25 hours.

Here's simple way:
private static int hoursDifference(Date date1, Date date2) {
final int MILLI_TO_HOUR = 1000 * 60 * 60;
return (int) (date1.getTime() - date2.getTime()) / MILLI_TO_HOUR;
}

java.time.Duration
I should like to contribute the modern (java 8+) answer. The solutions using Joda-Time are fine. The Joda-Time project is in maintenance mode, so for new code we should not use it. I follow the official recommendation from the Joda-Time project and use java.time, the modern Java date and time API:
Duration dur = Duration.between(startDate, endDate);
String result = String.format("%d:%02d", dur.toHours(), dur.toMinutesPart());
System.out.println(result);
This works if startDate and endDate both have type Instant or OffsetDateTime or ZonedDateTime or LocalDateTime or LocalTime. All of the mentioned types are from java.time package. If starting with LocalDate, call either of the atStartOfDay methods.
The toMinutesPart methof was introduced in Java 9. If you are using Java 8 (ot ThreeTen Backport), search for java format duration or similar to learn how to format the duration into hours and minutes.
Two quotes from the Joda-Time home page:
Users are now asked to migrate to java.time (JSR-310).
Note that Joda-Time is considered to be a largely “finished” project.
No major enhancements are planned. If using Java SE 8, please migrate
to java.time (JSR-310).
Links
Oracle tutorial: Date Time explaining how to use java.time.
Joda-Time home page

Please follow Somaiah's suggestion in a comment, use Hours instead:
Hours hours = Hours.hoursBetween(startTime, endTime);
The call to getHours() will only return the hour section of the time difference and ignore all year, month differences so it would not be correct in some cases.
If you use Period.toStandardHours() to try to convert the time difference into hours the calculation will throw an exception if the time difference between the two dates includes difference in either year or month, since the length of month is unknown.

So the getTime() method, I presume, returns an integer.
In which case, the left set of parentheses has type int, right?
and
(60*60*1000)
is also an int.
Which means you get long diff = ((int)/(int)) so the integer division is done BEFORE you cast stuff to long. And hence you lose your minutes.
Try casting them BEFORE you divide.

for kotlin, you can use below function and get hours between two date
private val dateFormat: String = "yyyy-MM-dd # hh:mm a"
val startDate = SimpleDateFormat(dateFormat).parse("2018-10-01 # 12:33 PM")
val endDate = SimpleDateFormat(dateFormat).parse("2018-10-01 # 02:46 PM")
private fun hoursDifference(date1: Date, date2: Date): Int {
val milliToHour : Long = 1000 * 60 * 60
return ((date1.time - date2.time) / milliToHour).toInt()
}
println(hoursDifference(endDate,startDate).toString())
Output:
2

Even though there's already an accepted answer, this is what worked for me using the Joda time library.
/**
*
* #param date1
* #param date2
* #return hours between two dates rounded down
*/
public static int hoursBetween(DateTime date1, DateTime date2) {
if(date1 == null || date2 == null) return NOT_FOUND;
return Math.abs(Hours.hoursBetween(date1.toLocalDateTime(), date2.toLocalDateTime()).getHours());
}

private void getHours(Date d1, Date d2){
long diff = d2.getTime() - d1.getTime();
long diffSeconds = diff / 1000 % 60;
long diffMinutes = diff / (60 * 1000) % 60;
long diffDays = diff / (24 * 60 * 60 * 1000);
long diffHours = diff / (60 * 60 * 1000) % 24;
System.out.print(diffDays + " days, ");
System.out.print(diffHours + " hours, ");
System.out.print(diffMinutes + " minutes, ");
System.out.print(diffSeconds + " seconds.\n");
}`
//Displays:
/* 1 days, 1 hours, 1 minutes, 50 seconds. */

Here's a pure Java 8+ solution that does not involve Joda or mathematical operations
import java.time.*;
import java.time.temporal.*;
// given two java.util.Dates
Date startDate ...
Date endDate ...
// convert them to ZonedDateTime instances
ZonedDateTime start = ZonedDateTime.ofInstant(startDate.toInstant(), ZoneId.systemDefault());
ZonedDateTime end = ZonedDateTime.ofInstant(endDate.toInstant(), ZoneId.systemDefault());
// get the total duration of minutes between them
Duration total = Duration.ofMinutes(ChronoUnit.MINUTES.between(start, end));
// use the duration to determine the hours and minutes values
long hours = total.toHours();
long minutes = total.minusHours(hours).toMinutes();

Here is the simple method :-
Check your Date format,if your date not in this format then change it and pass to this method it will give you a String which is your result. Modify the method as per the requirement.
private String getDateAsTime(String datePrev) {
String daysAsTime = "";
long day = 0, diff = 0;
String outputPattern = "yyyy:MM:dd HH:mm:ss";
SimpleDateFormat outputFormat = new SimpleDateFormat(outputPattern);
Calendar c = Calendar.getInstance();
String dateCurrent = outputFormat.format(c.getTime());
try {
Date date1 = outputFormat.parse(datePrev);
Date date2 = outputFormat.parse(dateCurrent);
diff = date2.getTime() - date1.getTime();
day = TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS);
} catch (ParseException e) {
e.printStackTrace();
}
if (day == 0) {
long hour = TimeUnit.HOURS.convert(diff, TimeUnit.MILLISECONDS);
if (hour == 0)
daysAsTime = String.valueOf(TimeUnit.MINUTES.convert(diff, TimeUnit.MILLISECONDS)).concat(" minutes ago");
else
daysAsTime = String.valueOf(hour).concat(" hours ago");
} else {
daysAsTime = String.valueOf(day).concat(" days ago");
}
return daysAsTime;
}
Hope this will help,

Related

Find Diffrence between two dates with time zones java/android

I am trying to find the difference between two java dates with time zone.
Time zone is GMT.Sever sends the time in this format 2015-04-08 11:17:53 -0400. I want to find the difference (in minutes)between server sent date format and current android system time.
I am finding the difference like this.c_date is the server date format(2015-04-08 11:17:53 -0400)
public static long getDiffrenceBetween(String c_date,String old_date) {
System.out.println("Cuttent Time :::"+c_date);
System.out.println("Saved/Old Time :::"+old_date);
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
format.setTimeZone(TimeZone.getTimeZone("GMT"));
Date d1 = null;
Date d2 = null;
long min_In_Minutes=0;
try {
d1 = format.parse(c_date);
d2 = format.parse(old_date);
// in milliseconds
long diff = d1.getTime() - d2.getTime();
min_In_Minutes = TimeUnit.MILLISECONDS.toMinutes(diff);
System.out.println("Diff in Minutes :::"+min_In_Minutes);
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.println(diffDays + " days, ");
System.out.println(diffHours + " hours, ");
System.out.println(diffMinutes + " minutes, ");
System.out.println(diffSeconds + " seconds.");
} catch (Exception e) {
e.printStackTrace();
}
return min_In_Minutes;
}
but this is giving negative value in minutes. what is wrong in this method. Please suggest.
Hoping that can find a solution here.
Thanks in advance,
sharath.
As you are using Android you obiosly cant use Java 8 and its new time api so I would reccomand using Joda-time - an external library for time.
Example for between calculation:
Seconds.between(startDate, endDate);
More details here: joda
GMT is the time anywhere in the world. GMT time code shows the difference between GMT and your local time. So theoretically ,
if your local time code is +/- "GMT 5.00"
difference between GMT and your local time = 5 * 60 minutes

Date difference in Java 23 hours day

I have to calculate the difference between to dates, I have found a way but I have this strange result, Am I missing something?
public static void main(String[] args) throws ParseException {
DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
long result = format.parse("2012-03-25 24:00").getTime() - format.parse("2012-03-25 00:00").getTime();
System.out.println("Difference in hours: " + result/(1000*60*60));
result = format.parse("2012-03-26 24:00").getTime() - format.parse("2012-03-26 00:00").getTime();
System.out.println("Difference in hours: " + result/(1000*60*60));
}
This is the result:
Difference in hours: 23
Difference in hours: 24
Thanks for the advices, now I'm using the Joda libray, I have this question, when I calculate the difference in this way:
DateTime begin = new DateTime("2012-03-25T00:00+01:00");
DateTime end = new DateTime("2012-03-26T00:00+01:00");
Hours m = Hours.hoursBetween(begin, end);
If I use this way to calculate the hours I get 24 hours (because the DST is not considered I assume)
What class/calculus should I use in order to get as result the 23 hours considering the DST (I have already tried different ways but I don't get it) the Period class?
Thanks for all the help...
Chances are you happen to have picked a date where daylight saving time changed in that time zone, so the day could really have been only 23 hours long. (March 25th 2012 certainly was the DST change date for Europe, e.g. Europe/London. We don't know what your default time zone is though.)
If you set your date format to use UTC, you shouldn't see this effect. (It's somewhat odd to use 24:00 in a string representation, mind you.) It's not clear what your data is meant to represent though, or what you're trying to measure. You should work out what time zone your data is really meant to be in, if you want to work out how much time actually elapsed between those local times.
(As noted in another answer, Joda Time is a much better API in general - but you still need to know how to use it properly, and when trying to work out the actual elapsed time, you'd still have seen the same results here.)
Must place the library file like explained below.
import java.util.Date;
String dateStart = dateChooserCombo1.getText();
String dateStop =dateChooserCombo2.getText();
//HH converts hour in 24 hours format (0-23), day calculation
SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy");
Date d1 = null;
Date d2 = null;
try {
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, ");
jTextField3.setText(""+diffDays);
} catch (Exception e) {
e.printStackTrace();
}

Android/Java - Date Difference in days

I am getting the current date (in format 12/31/1999 i.e. mm/dd/yyyy) as using the below code:
Textview txtViewData;
txtViewDate.setText("Today is " +
android.text.format.DateFormat.getDateFormat(this).format(new Date()));
and I am having another date in format as: 2010-08-25 (i.e. yyyy/mm/dd) ,
so I want to find the difference between date in number of days, how do I find difference in days?
(In other words, I want to find the difference between CURRENT DATE - yyyy/mm/dd formatted date)
Not really a reliable method, better of using JodaTime
Calendar thatDay = Calendar.getInstance();
thatDay.set(Calendar.DAY_OF_MONTH,25);
thatDay.set(Calendar.MONTH,7); // 0-11 so 1 less
thatDay.set(Calendar.YEAR, 1985);
Calendar today = Calendar.getInstance();
long diff = today.getTimeInMillis() - thatDay.getTimeInMillis(); //result in millis
Here's an approximation...
long days = diff / (24 * 60 * 60 * 1000);
To Parse the date from a string, you could use
String strThatDay = "1985/08/25";
SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
Date d = null;
try {
d = formatter.parse(strThatDay);//catch exception
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Calendar thatDay = Calendar.getInstance();
thatDay.setTime(d); //rest is the same....
Although, since you're sure of the date format...
You Could also do Integer.parseInt() on it's Substrings to obtain their numeric values.
This is NOT my work, found the answer here. did not want a broken link in the future :).
The key is this line for taking daylight setting into account, ref Full Code.
TimeZone.setDefault(TimeZone.getTimeZone("Europe/London"));
or try passing TimeZone as a parameter to daysBetween() and call setTimeZone() in the sDate and eDate objects.
So here it goes:
public static Calendar getDatePart(Date date){
Calendar cal = Calendar.getInstance(); // get calendar instance
cal.setTime(date);
cal.set(Calendar.HOUR_OF_DAY, 0); // set hour to midnight
cal.set(Calendar.MINUTE, 0); // set minute in hour
cal.set(Calendar.SECOND, 0); // set second in minute
cal.set(Calendar.MILLISECOND, 0); // set millisecond in second
return cal; // return the date part
}
getDatePart() taken from here
/**
* This method also assumes endDate >= startDate
**/
public static long daysBetween(Date startDate, Date endDate) {
Calendar sDate = getDatePart(startDate);
Calendar eDate = getDatePart(endDate);
long daysBetween = 0;
while (sDate.before(eDate)) {
sDate.add(Calendar.DAY_OF_MONTH, 1);
daysBetween++;
}
return daysBetween;
}
The Nuances:
Finding the difference between two dates isn't as straightforward as subtracting the two dates and dividing the result by (24 * 60 * 60 * 1000). Infact, its erroneous!
For example: The difference between the two dates 03/24/2007 and 03/25/2007 should be 1 day; However, using the above method, in the UK, you'll get 0 days!
See for yourself (code below). Going the milliseconds way will lead to rounding off errors and they become most evident once you have a little thing like Daylight Savings Time come into the picture.
Full Code:
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class DateTest {
public class DateTest {
static SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy");
public static void main(String[] args) {
TimeZone.setDefault(TimeZone.getTimeZone("Europe/London"));
//diff between these 2 dates should be 1
Date d1 = new Date("01/01/2007 12:00:00");
Date d2 = new Date("01/02/2007 12:00:00");
//diff between these 2 dates should be 1
Date d3 = new Date("03/24/2007 12:00:00");
Date d4 = new Date("03/25/2007 12:00:00");
Calendar cal1 = Calendar.getInstance();cal1.setTime(d1);
Calendar cal2 = Calendar.getInstance();cal2.setTime(d2);
Calendar cal3 = Calendar.getInstance();cal3.setTime(d3);
Calendar cal4 = Calendar.getInstance();cal4.setTime(d4);
printOutput("Manual ", d1, d2, calculateDays(d1, d2));
printOutput("Calendar ", d1, d2, daysBetween(cal1, cal2));
System.out.println("---");
printOutput("Manual ", d3, d4, calculateDays(d3, d4));
printOutput("Calendar ", d3, d4, daysBetween(cal3, cal4));
}
private static void printOutput(String type, Date d1, Date d2, long result) {
System.out.println(type+ "- Days between: " + sdf.format(d1)
+ " and " + sdf.format(d2) + " is: " + result);
}
/** Manual Method - YIELDS INCORRECT RESULTS - DO NOT USE**/
/* This method is used to find the no of days between the given dates */
public static long calculateDays(Date dateEarly, Date dateLater) {
return (dateLater.getTime() - dateEarly.getTime()) / (24 * 60 * 60 * 1000);
}
/** Using Calendar - THE CORRECT WAY**/
public static long daysBetween(Date startDate, Date endDate) {
...
}
OUTPUT:
Manual - Days between: 01-Jan-2007 and 02-Jan-2007 is: 1
Calendar - Days between: 01-Jan-2007 and 02-Jan-2007 is: 1
Manual - Days between: 24-Mar-2007 and 25-Mar-2007 is: 0
Calendar - Days between: 24-Mar-2007 and 25-Mar-2007 is: 1
Most of the answers were good and right for your problem of
so i want to find the difference between date in number of days, how do i find difference in days?
I suggest this very simple and straightforward approach that is guaranteed to give you the correct difference in any time zone:
int difference=
((int)((startDate.getTime()/(24*60*60*1000))
-(int)(endDate.getTime()/(24*60*60*1000))));
And that's it!
Use jodatime API
Days.daysBetween(start.toDateMidnight() , end.toDateMidnight() ).getDays()
where 'start' and 'end' are your DateTime objects. To parse your date Strings into DateTime objects use the parseDateTime method
There is also an android specific JodaTime library.
This fragment accounts for daylight savings time and is O(1).
private final static long MILLISECS_PER_DAY = 24 * 60 * 60 * 1000;
private static long getDateToLong(Date date) {
return Date.UTC(date.getYear(), date.getMonth(), date.getDate(), 0, 0, 0);
}
public static int getSignedDiffInDays(Date beginDate, Date endDate) {
long beginMS = getDateToLong(beginDate);
long endMS = getDateToLong(endDate);
long diff = (endMS - beginMS) / (MILLISECS_PER_DAY);
return (int)diff;
}
public static int getUnsignedDiffInDays(Date beginDate, Date endDate) {
return Math.abs(getSignedDiffInDays(beginDate, endDate));
}
This is Simple and best calculation for me and may be for you.
try {
/// String CurrDate= "10/6/2013";
/// String PrvvDate= "10/7/2013";
Date date1 = null;
Date date2 = null;
SimpleDateFormat df = new SimpleDateFormat("M/dd/yyyy");
date1 = df.parse(CurrDate);
date2 = df.parse(PrvvDate);
long diff = Math.abs(date1.getTime() - date2.getTime());
long diffDays = diff / (24 * 60 * 60 * 1000);
System.out.println(diffDays);
} catch (Exception e1) {
System.out.println("exception " + e1);
}
tl;dr
ChronoUnit.DAYS.between(
LocalDate.parse( "1999-12-28" ) ,
LocalDate.parse( "12/31/1999" , DateTimeFormatter.ofPattern( "MM/dd/yyyy" ) )
)
Details
Other answers are outdated. The old date-time classes bundled with the earliest versions of Java have proven to be poorly designed, confusing, and troublesome. Avoid them.
java.time
The Joda-Time project was highly successful as a replacement for those old classes. These classes provided the inspiration for the java.time framework built into Java 8 and later.
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP.
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone.
Parsing strings
If your input strings are in standard ISO 8601 format, the LocalDate class can directly parse the string.
LocalDate start = LocalDate.parse( "1999-12-28" );
If not in ISO 8601 format, define a formatting pattern with DateTimeFormatter.
String input = "12/31/1999";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "MM/dd/yyyy" );
LocalDate stop = LocalDate.parse( input , formatter );
Elapsed days via ChronoUnit
Now get a count of days elapsed between that pair of LocalDate objects. The ChronoUnit enum calculates elapsed time.
long totalDays = ChronoUnit.DAYS.between( start , stop ) ;
If you are unfamiliar with Java enums, know they are far more powerful and useful that conventional enums in most other programming languages. See the Enum class doc, the Oracle Tutorial, and Wikipedia to learn more.
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 the java.time classes.
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 ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
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.
The Correct Way from Sam Quest's answer only works if the first date is earlier than the second. Moreover, it will return 1 if the two dates are within a single day.
This is the solution that worked best for me. Just like most other solutions, it would still show incorrect results on two days in a year because of wrong day light saving offset.
private final static long MILLISECS_PER_DAY = 24 * 60 * 60 * 1000;
long calculateDeltaInDays(Calendar a, Calendar b) {
// Optional: avoid cloning objects if it is the same day
if(a.get(Calendar.ERA) == b.get(Calendar.ERA)
&& a.get(Calendar.YEAR) == b.get(Calendar.YEAR)
&& a.get(Calendar.DAY_OF_YEAR) == b.get(Calendar.DAY_OF_YEAR)) {
return 0;
}
Calendar a2 = (Calendar) a.clone();
Calendar b2 = (Calendar) b.clone();
a2.set(Calendar.HOUR_OF_DAY, 0);
a2.set(Calendar.MINUTE, 0);
a2.set(Calendar.SECOND, 0);
a2.set(Calendar.MILLISECOND, 0);
b2.set(Calendar.HOUR_OF_DAY, 0);
b2.set(Calendar.MINUTE, 0);
b2.set(Calendar.SECOND, 0);
b2.set(Calendar.MILLISECOND, 0);
long diff = a2.getTimeInMillis() - b2.getTimeInMillis();
long days = diff / MILLISECS_PER_DAY;
return Math.abs(days);
}
best and easiest way to do this
public int getDays(String begin) throws ParseException {
long MILLIS_PER_DAY = 24 * 60 * 60 * 1000;
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy", Locale.ENGLISH);
long begin = dateFormat.parse(begin).getTime();
long end = new Date().getTime(); // 2nd date want to compare
long diff = (end - begin) / (MILLIS_PER_DAY);
return (int) diff;
}
Use the following functions:
/**
* Returns the number of days between two dates. The time part of the
* days is ignored in this calculation, so 2007-01-01 13:00 and 2007-01-02 05:00
* have one day inbetween.
*/
public static long daysBetween(Date firstDate, Date secondDate) {
// We only use the date part of the given dates
long firstSeconds = truncateToDate(firstDate).getTime()/1000;
long secondSeconds = truncateToDate(secondDate).getTime()/1000;
// Just taking the difference of the millis.
// These will not be exactly multiples of 24*60*60, since there
// might be daylight saving time somewhere inbetween. However, we can
// say that by adding a half day and rounding down afterwards, we always
// get the full days.
long difference = secondSeconds-firstSeconds;
// Adding half a day
if( difference >= 0 ) {
difference += SECONDS_PER_DAY/2; // plus half a day in seconds
} else {
difference -= SECONDS_PER_DAY/2; // minus half a day in seconds
}
// Rounding down to days
difference /= SECONDS_PER_DAY;
return difference;
}
/**
* Truncates a date to the date part alone.
*/
#SuppressWarnings("deprecation")
public static Date truncateToDate(Date d) {
if( d instanceof java.sql.Date ) {
return d; // java.sql.Date is already truncated to date. And raises an
// Exception if we try to set hours, minutes or seconds.
}
d = (Date)d.clone();
d.setHours(0);
d.setMinutes(0);
d.setSeconds(0);
d.setTime(((d.getTime()/1000)*1000));
return d;
}
There's a simple solution, that at least for me, is the only feasible solution.
The problem is that all the answers I see being tossed around - using Joda, or Calendar, or Date, or whatever - only take the amount of milliseconds into consideration. They end up counting the number of 24-hour cycles between two dates, rather than the actual number of days. So something from Jan 1st 11pm to Jan 2nd 1am will return 0 days.
To count the actual number of days between startDate and endDate, simply do:
// Find the sequential day from a date, essentially resetting time to start of the day
long startDay = startDate.getTime() / 1000 / 60 / 60 / 24;
long endDay = endDate.getTime() / 1000 / 60 / 60 / 24;
// Find the difference, duh
long daysBetween = endDay - startDay;
This will return "1" between Jan 2nd and Jan 1st. If you need to count the end day, just add 1 to daysBetween (I needed to do that in my code since I wanted to count the total number of days in the range).
This is somewhat similar to what Daniel has suggested but smaller code I suppose.
All of these solutions suffer from one of two problems. Either the solution isn't perfectly accurate due to rounding errors, leap days and seconds, etc. or you end up looping over the number of days in between your two unknown dates.
This solution solves the first problem, and improves the second by a factor of roughly 365, better if you know what your max range is.
/**
* #param thisDate
* #param thatDate
* #param maxDays
* set to -1 to not set a max
* #returns number of days covered between thisDate and thatDate, inclusive, i.e., counting both
* thisDate and thatDate as an entire day. Will short out if the number of days exceeds
* or meets maxDays
*/
public static int daysCoveredByDates(Date thisDate, Date thatDate, int maxDays) {
//Check inputs
if (thisDate == null || thatDate == null) {
return -1;
}
//Set calendar objects
Calendar startCal = Calendar.getInstance();
Calendar endCal = Calendar.getInstance();
if (thisDate.before(thatDate)) {
startCal.setTime(thisDate);
endCal.setTime(thatDate);
}
else {
startCal.setTime(thatDate);
endCal.setTime(thisDate);
}
//Get years and dates of our times.
int startYear = startCal.get(Calendar.YEAR);
int endYear = endCal.get(Calendar.YEAR);
int startDay = startCal.get(Calendar.DAY_OF_YEAR);
int endDay = endCal.get(Calendar.DAY_OF_YEAR);
//Calculate the number of days between dates. Add up each year going by until we catch up to endDate.
while (startYear < endYear && maxDays >= 0 && endDay - startDay + 1 < maxDays) {
endDay += startCal.getActualMaximum(Calendar.DAY_OF_YEAR); //adds the number of days in the year startDate is currently in
++startYear;
startCal.set(Calendar.YEAR, startYear); //reup the year
}
int days = endDay - startDay + 1;
//Honor the maximum, if set
if (maxDays >= 0) {
days = Math.min(days, maxDays);
}
return days;
}
If you need days between dates (uninclusive of the latter date), just get rid of the + 1 when you see endDay - startDay + 1.
One another way:
public static int numberOfDaysBetweenDates(Calendar fromDay, Calendar toDay) {
fromDay = calendarStartOfDay(fromDay);
toDay = calendarStartOfDay(toDay);
long from = fromDay.getTimeInMillis();
long to = toDay.getTimeInMillis();
return (int) TimeUnit.MILLISECONDS.toDays(to - from);
}
Date userDob = new SimpleDateFormat("yyyy-MM-dd").parse(dob);
Date today = new Date();
long diff = today.getTime() - userDob.getTime();
int numOfDays = (int) (diff / (1000 * 60 * 60 * 24));
int hours = (int) (diff / (1000 * 60 * 60));
int minutes = (int) (diff / (1000 * 60));
int seconds = (int) (diff / (1000));
use these functions
public static int getDateDifference(int previousYear, int previousMonthOfYear, int previousDayOfMonth, int nextYear, int nextMonthOfYear, int nextDayOfMonth, int differenceToCount){
// int differenceToCount = can be any of the following
// Calendar.MILLISECOND;
// Calendar.SECOND;
// Calendar.MINUTE;
// Calendar.HOUR;
// Calendar.DAY_OF_MONTH;
// Calendar.MONTH;
// Calendar.YEAR;
// Calendar.----
Calendar previousDate = Calendar.getInstance();
previousDate.set(Calendar.DAY_OF_MONTH, previousDayOfMonth);
// month is zero indexed so month should be minus 1
previousDate.set(Calendar.MONTH, previousMonthOfYear);
previousDate.set(Calendar.YEAR, previousYear);
Calendar nextDate = Calendar.getInstance();
nextDate.set(Calendar.DAY_OF_MONTH, previousDayOfMonth);
// month is zero indexed so month should be minus 1
nextDate.set(Calendar.MONTH, previousMonthOfYear);
nextDate.set(Calendar.YEAR, previousYear);
return getDateDifference(previousDate,nextDate,differenceToCount);
}
public static int getDateDifference(Calendar previousDate,Calendar nextDate,int differenceToCount){
// int differenceToCount = can be any of the following
// Calendar.MILLISECOND;
// Calendar.SECOND;
// Calendar.MINUTE;
// Calendar.HOUR;
// Calendar.DAY_OF_MONTH;
// Calendar.MONTH;
// Calendar.YEAR;
// Calendar.----
//raise an exception if previous is greater than nextdate.
if(previousDate.compareTo(nextDate)>0){
throw new RuntimeException("Previous Date is later than Nextdate");
}
int difference=0;
while(previousDate.compareTo(nextDate)<=0){
difference++;
previousDate.add(differenceToCount,1);
}
return difference;
}
public void dateDifferenceExample() {
// Set the date for both of the calendar instance
GregorianCalendar calDate = new GregorianCalendar(2012, 10, 02,5,23,43);
GregorianCalendar cal2 = new GregorianCalendar(2015, 04, 02);
// Get the represented date in milliseconds
long millis1 = calDate.getTimeInMillis();
long millis2 = cal2.getTimeInMillis();
// Calculate difference in milliseconds
long diff = millis2 - millis1;
// Calculate difference in seconds
long diffSeconds = diff / 1000;
// Calculate difference in minutes
long diffMinutes = diff / (60 * 1000);
// Calculate difference in hours
long diffHours = diff / (60 * 60 * 1000);
// Calculate difference in days
long diffDays = diff / (24 * 60 * 60 * 1000);
Toast.makeText(getContext(), ""+diffSeconds, Toast.LENGTH_SHORT).show();
}
I found a very easy way to do this and it's what I'm using in my app.
Let's say you have the dates in Time objects (or whatever, we just need the milliseconds):
Time date1 = initializeDate1(); //get the date from somewhere
Time date2 = initializeDate2(); //get the date from somewhere
long millis1 = date1.toMillis(true);
long millis2 = date2.toMillis(true);
long difference = millis2 - millis1 ;
//now get the days from the difference and that's it
long days = TimeUnit.MILLISECONDS.toDays(difference);
//now you can do something like
if(days == 7)
{
//do whatever when there's a week of difference
}
if(days >= 30)
{
//do whatever when it's been a month or more
}
Joda-Time
Best way is to use Joda-Time, the highly successful open-source library you would add to your project.
String date1 = "2015-11-11";
String date2 = "2013-11-11";
DateTimeFormatter formatter = new DateTimeFormat.forPattern("yyyy-MM-dd");
DateTime d1 = formatter.parseDateTime(date1);
DateTime d2 = formatter.parseDateTime(date2);
long diffInMillis = d2.getMillis() - d1.getMillis();
Duration duration = new Duration(d1, d2);
int days = duration.getStandardDays();
int hours = duration.getStandardHours();
int minutes = duration.getStandardMinutes();
If you're using Android Studio, very easy to add joda-time. In your build.gradle (app):
dependencies {
compile 'joda-time:joda-time:2.4'
compile 'joda-time:joda-time:2.4'
compile 'joda-time:joda-time:2.2'
}

Difference in days between two dates in Java?

I need to find the number of days between two dates: one is from a report and one is the current date. My snippet:
int age=calculateDifference(agingDate, today);
Here calculateDifference is a private method, agingDate and today are Date objects, just for your clarification. I've followed two articles from a Java forum, Thread 1 / Thread 2.
It works fine in a standalone program although when I include this into my logic to read from the report I get an unusual difference in values.
Why is it happening and how can I fix it?
EDIT :
I'm getting a greater number of days compared to the actual amount of Days.
public static int calculateDifference(Date a, Date b)
{
int tempDifference = 0;
int difference = 0;
Calendar earlier = Calendar.getInstance();
Calendar later = Calendar.getInstance();
if (a.compareTo(b) < 0)
{
earlier.setTime(a);
later.setTime(b);
}
else
{
earlier.setTime(b);
later.setTime(a);
}
while (earlier.get(Calendar.YEAR) != later.get(Calendar.YEAR))
{
tempDifference = 365 * (later.get(Calendar.YEAR) - earlier.get(Calendar.YEAR));
difference += tempDifference;
earlier.add(Calendar.DAY_OF_YEAR, tempDifference);
}
if (earlier.get(Calendar.DAY_OF_YEAR) != later.get(Calendar.DAY_OF_YEAR))
{
tempDifference = later.get(Calendar.DAY_OF_YEAR) - earlier.get(Calendar.DAY_OF_YEAR);
difference += tempDifference;
earlier.add(Calendar.DAY_OF_YEAR, tempDifference);
}
return difference;
}
Note :
Unfortunately, none of the answers helped me solve the problem. I've accomplished this problem with the help of Joda-time library.
I would suggest you use the excellent Joda Time library instead of the flawed java.util.Date and friends. You could simply write
import java.util.Date;
import org.joda.time.DateTime;
import org.joda.time.Days;
Date past = new Date(110, 5, 20); // June 20th, 2010
Date today = new Date(110, 6, 24); // July 24th
int days = Days.daysBetween(new DateTime(past), new DateTime(today)).getDays(); // => 34
I might be too late to join the game but what the heck huh? :)
Do you think this is a threading issue? How are you using the output of this method for example? OR
Can we change your code to do something as simple as:
Calendar calendar1 = Calendar.getInstance();
Calendar calendar2 = Calendar.getInstance();
calendar1.set(<your earlier date>);
calendar2.set(<your current date>);
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.");
}
The diff / (24 * etc) does not take Timezone into account, so if your default timezone has a DST in it, it can throw the calculation off.
This link has a nice little implementation.
Here is the source of the above link in case the link goes down:
/** Using Calendar - THE CORRECT WAY**/
public static long daysBetween(Calendar startDate, Calendar endDate) {
//assert: startDate must be before endDate
Calendar date = (Calendar) startDate.clone();
long daysBetween = 0;
while (date.before(endDate)) {
date.add(Calendar.DAY_OF_MONTH, 1);
daysBetween++;
}
return daysBetween;
}
and
/** Using Calendar - THE CORRECT (& Faster) WAY**/
public static long daysBetween(final Calendar startDate, final Calendar endDate)
{
//assert: startDate must be before endDate
int MILLIS_IN_DAY = 1000 * 60 * 60 * 24;
long endInstant = endDate.getTimeInMillis();
int presumedDays =
(int) ((endInstant - startDate.getTimeInMillis()) / MILLIS_IN_DAY);
Calendar cursor = (Calendar) startDate.clone();
cursor.add(Calendar.DAY_OF_YEAR, presumedDays);
long instant = cursor.getTimeInMillis();
if (instant == endInstant)
return presumedDays;
final int step = instant < endInstant ? 1 : -1;
do {
cursor.add(Calendar.DAY_OF_MONTH, step);
presumedDays += step;
} while (cursor.getTimeInMillis() != endInstant);
return presumedDays;
}
java.time
In Java 8 and later, use the java.time framework (Tutorial).
Duration
The Duration class represents a span of time as a number of seconds plus a fractional second. It can count days, hours, minutes, and seconds.
ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime oldDate = now.minusDays(1).minusMinutes(10);
Duration duration = Duration.between(oldDate, now);
System.out.println(duration.toDays());
ChronoUnit
If all you need is the number of days, alternatively you can use the ChronoUnit enum. Notice the calculation methods return a long rather than int.
long days = ChronoUnit.DAYS.between( then, now );
import java.util.Calendar;
import java.util.Date;
public class Main {
public static long calculateDays(String startDate, String endDate)
{
Date sDate = new Date(startDate);
Date eDate = new Date(endDate);
Calendar cal3 = Calendar.getInstance();
cal3.setTime(sDate);
Calendar cal4 = Calendar.getInstance();
cal4.setTime(eDate);
return daysBetween(cal3, cal4);
}
public static void main(String[] args) {
System.out.println(calculateDays("2012/03/31", "2012/06/17"));
}
/** 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;
}
}
It depends on what you define as the difference. To compare two dates at midnight you can do.
long day1 = ...; // in milliseconds.
long day2 = ...; // in milliseconds.
long days = (day2 - day1) / 86400000;
Solution using difference between milliseconds time, with correct rounding for DST dates:
public static long daysDiff(Date from, Date to) {
return daysDiff(from.getTime(), to.getTime());
}
public static long daysDiff(long from, long to) {
return Math.round( (to - from) / 86400000D ); // 1000 * 60 * 60 * 24
}
One note: Of course, dates must be in some timezone.
The important code:
Math.round( (to - from) / 86400000D )
If you don't want round, you can use UTC dates,
Illustration of the problem: (My code is computing delta in weeks, but same issue applies with delta in days)
Here is a very reasonable-looking implementation:
public static final long MILLIS_PER_WEEK = 7L * 24L * 60L * 60L * 1000L;
static public int getDeltaInWeeks(Date latterDate, Date earlierDate) {
long deltaInMillis = latterDate.getTime() - earlierDate.getTime();
int deltaInWeeks = (int)(deltaInMillis / MILLIS_PER_WEEK);
return deltaInWeeks;
}
But this test will fail:
public void testGetDeltaInWeeks() {
delta = AggregatedData.getDeltaInWeeks(dateMar09, dateFeb23);
assertEquals("weeks between Feb23 and Mar09", 2, delta);
}
The reason is:
Mon Mar 09 00:00:00 EDT 2009 = 1,236,571,200,000 Mon Feb 23
00:00:00 EST 2009 = 1,235,365,200,000 MillisPerWeek =
604,800,000 Thus, (Mar09 - Feb23) / MillisPerWeek =
1,206,000,000 / 604,800,000 = 1.994...
but anyone looking at a calendar would agree that the answer is 2.
I use this funcion:
DATEDIFF("31/01/2016", "01/03/2016") // me return 30 days
my function:
import java.util.Date;
public long DATEDIFF(String date1, String date2) {
long MILLISECS_PER_DAY = 24 * 60 * 60 * 1000;
long days = 0l;
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy"); // "dd/MM/yyyy HH:mm:ss");
Date dateIni = null;
Date dateFin = null;
try {
dateIni = (Date) format.parse(date1);
dateFin = (Date) format.parse(date2);
days = (dateFin.getTime() - dateIni.getTime())/MILLISECS_PER_DAY;
} catch (Exception e) { e.printStackTrace(); }
return days;
}
Look at the getFragmentInDays methods in this apache commons-lang class DateUtils.
Based on #Mad_Troll's answer, I developed this method.
I've run about 30 test cases against it, is the only method that handles sub day time fragments correctly.
Example: If you pass now & now + 1 millisecond that is still the same day.
Doing 1-1-13 23:59:59.098 to 1-1-13 23:59:59.099 returns 0 days, correctly; allot of the other methods posted here will not do this correctly.
Worth noting it does not care about which way you put them in, If your end date is before your start date it will count backwards.
/**
* This is not quick but if only doing a few days backwards/forwards then it is very accurate.
*
* #param startDate from
* #param endDate to
* #return day count between the two dates, this can be negative if startDate is after endDate
*/
public static long daysBetween(#NotNull final Calendar startDate, #NotNull final Calendar endDate) {
//Forwards or backwards?
final boolean forward = startDate.before(endDate);
// Which direction are we going
final int multiplier = forward ? 1 : -1;
// The date we are going to move.
final Calendar date = (Calendar) startDate.clone();
// Result
long daysBetween = 0;
// Start at millis (then bump up until we go back a day)
int fieldAccuracy = 4;
int field;
int dayBefore, dayAfter;
while (forward && date.before(endDate) || !forward && endDate.before(date)) {
// We start moving slowly if no change then we decrease accuracy.
switch (fieldAccuracy) {
case 4:
field = Calendar.MILLISECOND;
break;
case 3:
field = Calendar.SECOND;
break;
case 2:
field = Calendar.MINUTE;
break;
case 1:
field = Calendar.HOUR_OF_DAY;
break;
default:
case 0:
field = Calendar.DAY_OF_MONTH;
break;
}
// Get the day before we move the time, Change, then get the day after.
dayBefore = date.get(Calendar.DAY_OF_MONTH);
date.add(field, multiplier);
dayAfter = date.get(Calendar.DAY_OF_MONTH);
// This shifts lining up the dates, one field at a time.
if (dayBefore == dayAfter && date.get(field) == endDate.get(field))
fieldAccuracy--;
// If day has changed after moving at any accuracy level we bump the day counter.
if (dayBefore != dayAfter) {
daysBetween += multiplier;
}
}
return daysBetween;
}
You can remove the #NotNull annotations, these are used by Intellij to do code analysis on the fly
You say it "works fine in a standalone program," but that you get "unusual difference values" when you "include this into my logic to read from report". That suggests that your report has some values for which it doesn't work correctly, and your standalone program doesn't have those values. Instead of a standalone program, I suggest a test case. Write a test case much as you would a standalone program, subclassing from JUnit's TestCase class. Now you can run a very specific example, knowing what value you expect (and don't give it today for the test value, because today changes over time). If you put in the values you used in the standalone program, your tests will probably pass. That's great - you want those cases to keep working. Now, add a value from your report, one that doesn't work right. Your new test will probably fail. Figure out why it's failing, fix it, and get to green (all tests passing). Run your report. See what's still broken; write a test; make it pass. Pretty soon you'll find your report is working.
Hundred lines of code for this basic function???
Just a simple method:
protected static int calculateDayDifference(Date dateAfter, Date dateBefore){
return (int)(dateAfter.getTime()-dateBefore.getTime())/(1000 * 60 * 60 * 24);
// MILLIS_IN_DAY = 1000 * 60 * 60 * 24;
}
public static int getDifferenceIndays(long timestamp1, long timestamp2) {
final int SECONDS = 60;
final int MINUTES = 60;
final int HOURS = 24;
final int MILLIES = 1000;
long temp;
if (timestamp1 < timestamp2) {
temp = timestamp1;
timestamp1 = timestamp2;
timestamp2 = temp;
}
Calendar startDate = Calendar.getInstance(TimeZone.getDefault());
Calendar endDate = Calendar.getInstance(TimeZone.getDefault());
endDate.setTimeInMillis(timestamp1);
startDate.setTimeInMillis(timestamp2);
if ((timestamp1 - timestamp2) < 1 * HOURS * MINUTES * SECONDS * MILLIES) {
int day1 = endDate.get(Calendar.DAY_OF_MONTH);
int day2 = startDate.get(Calendar.DAY_OF_MONTH);
if (day1 == day2) {
return 0;
} else {
return 1;
}
}
int diffDays = 0;
startDate.add(Calendar.DAY_OF_MONTH, diffDays);
while (startDate.before(endDate)) {
startDate.add(Calendar.DAY_OF_MONTH, 1);
diffDays++;
}
return diffDays;
}
ThreeTen-Extra
The Answer by Vitalii Fedorenko is correct, describing how to perform this calculation in a modern way with java.time classes (Duration & ChronoUnit) built into Java 8 and later (and back-ported to Java 6 & 7 and to Android).
Days
If you are using a number of days routinely in your code, you can replace mere integers with use of a class. The Days class can be found in the ThreeTen-Extra project, an extension of java.time and proving ground for possible future additions to java.time. The Days class provides a type-safe way of representing a number of days in your application. The class includes convenient constants for ZERO and ONE.
Given the old outmoded java.util.Date objects in the Question, first convert them to modern java.time.Instant objects. The old date-time classes have newly added methods to facilitate conversion to java.time, such a java.util.Date::toInstant.
Instant start = utilDateStart.toInstant(); // Inclusive.
Instant stop = utilDateStop.toInstant(); // Exclusive.
Pass both Instant objects to factory method for org.threeten.extra.Days.
In the current implementation (2016-06) this is a wrapper calling java.time.temporal.ChronoUnit.DAYS.between, read the ChronoUnit class doc for details. To be clear: all uppercase DAYS is in the enum ChronoUnit while initial-cap Days is a class from ThreeTen-Extra.
Days days = Days.between( start , stop );
You can pass these Days objects around your own code. You can serialize to a String in the standard ISO 8601 format by calling toString. This format of PnD uses a P to mark the beginning and D means “days”, with a number of days in between. Both java.time classes and ThreeTen-Extra use these standard formats by default when generating and parsing Strings representing date-time values.
String output = days.toString();
P3D
Days days = Days.parse( "P3D" );
This code calculates days between 2 date Strings:
static final long MILLI_SECONDS_IN_A_DAY = 1000 * 60 * 60 * 24;
static final String DATE_FORMAT = "dd-MM-yyyy";
public long daysBetween(String fromDateStr, String toDateStr) throws ParseException {
SimpleDateFormat format = new SimpleDateFormat(DATE_FORMAT);
Date fromDate;
Date toDate;
fromDate = format.parse(fromDateStr);
toDate = format.parse(toDateStr);
return (toDate.getTime() - fromDate.getTime()) / MILLI_SECONDS_IN_A_DAY;
}
If you're looking for a solution that returns proper number or days between e.g. 11/30/2014 23:59 and 12/01/2014 00:01 here's solution using Joda Time.
private int getDayDifference(long past, long current) {
DateTime currentDate = new DateTime(current);
DateTime pastDate = new DateTime(past);
return currentDate.getDayOfYear() - pastDate.getDayOfYear();
}
This implementation will return 1 as a difference in days. Most of the solutions posted here calculate difference in milliseconds between two dates. It means that 0 would be returned because there's only 2 minutes difference between these two dates.
You should use Joda Time library because Java Util Date returns wrong values sometimes.
Joda vs Java Util Date
For example days between yesterday (dd-mm-yyyy, 12-07-2016) and first day of year in 1957 (dd-mm-yyyy, 01-01-1957):
public class Main {
public static void main(String[] args) {
SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy");
Date date = null;
try {
date = format.parse("12-07-2016");
} catch (ParseException e) {
e.printStackTrace();
}
//Try with Joda - prints 21742
System.out.println("This is correct: " + getDaysBetweenDatesWithJodaFromYear1957(date));
//Try with Java util - prints 21741
System.out.println("This is not correct: " + getDaysBetweenDatesWithJavaUtilFromYear1957(date));
}
private static int getDaysBetweenDatesWithJodaFromYear1957(Date date) {
DateTime jodaDateTime = new DateTime(date);
DateTimeFormatter formatter = DateTimeFormat.forPattern("dd-MM-yyyy");
DateTime y1957 = formatter.parseDateTime("01-01-1957");
return Days.daysBetween(y1957 , jodaDateTime).getDays();
}
private static long getDaysBetweenDatesWithJavaUtilFromYear1957(Date date) {
SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy");
Date y1957 = null;
try {
y1957 = format.parse("01-01-1957");
} catch (ParseException e) {
e.printStackTrace();
}
return TimeUnit.DAYS.convert(date.getTime() - y1957.getTime(), TimeUnit.MILLISECONDS);
}
So I really advice you to use Joda Time library.
I did it this way. it's easy :)
Date d1 = jDateChooserFrom.getDate();
Date d2 = jDateChooserTo.getDate();
Calendar day1 = Calendar.getInstance();
day1.setTime(d1);
Calendar day2 = Calendar.getInstance();
day2.setTime(d2);
int from = day1.get(Calendar.DAY_OF_YEAR);
int to = day2.get(Calendar.DAY_OF_YEAR);
int difference = to-from;

Calculating the difference between two Java date instances

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?
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 can you 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()
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()
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.
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.
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:
P3Y6M4DT12H30M5Sthree years, six months, four days, twelve hours, thirty minutes, and five seconds
PT4H30MFour 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 ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use….
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
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?
Days d = Days.daysBetween(startDate, endDate);
int days = d.getDays();
https://www.joda.org/joda-time/faq.html#datediff
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).
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;
}
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 );
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.
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.
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
}
Take a look at Joda Time, which is an improved Date/Time API for Java and should work fine with Scala.
int daysDiff = (date1.getTime() - date2.getTime()) / MILLIS_PER_DAY;
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
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;
}
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;
}
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();
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.");
}
}
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));
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());
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";
}
}
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.
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;
}
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?
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);
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.
:)
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
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);
}

Categories

Resources