Java, Calculate the number of days between two dates [duplicate]
Possible Duplicate:
Calculating the Difference Between Two Java Date Instances
In Java, I want to calculate the number of days between two dates.
In my database they are stored as a DATE
datatype, but in my code they are strings.
I want to calculate the no of days between those two strings.
Note: this answer was written in 2011. I would recommend using java.time
now instead of Joda Time.
Well to start with, you should only deal with them as strings when you have to. Most of the time you should work with them in a data type which actually describes the data you're working with.
I would recommend that you use Joda Time, which is a much better API than Date
/Calendar
. It sounds like you should use the LocalDate
type in this case. You can then use:
int days = Days.daysBetween(date1, date2).getDays();
Java 8 and later: ChronoUnit.between
Use instances of ChronoUnit
to calculate amount of time in different units (days,months, seconds).
For Example:
ChronoUnit.DAYS.between(startDate,endDate)
try this code
Calendar cal1 = new GregorianCalendar();
Calendar cal2 = new GregorianCalendar();
SimpleDateFormat sdf = new SimpleDateFormat("ddMMyyyy");
Date date = sdf.parse("your first date");
cal1.setTime(date)
date = sdf.parse("your second date");
cal2.setTime(date);
//cal1.set(2008, 8, 1);
//cal2.set(2008, 9, 31);
System.out.println("Days= "+daysBetween(cal1.getTime(),cal2.getTime()));
this function
public int daysBetween(Date d1, Date d2){
return (int)( (d2.getTime() - d1.getTime()) / (1000 * 60 * 60 * 24));
}
I know this thread is two years old now, I still don't see a correct answer here.
Unless you want to use Joda or have Java 8 and if you need to subract dates influenced by daylight saving.
So I have written my own solution. The important aspect is that it only works if you really only care about dates because it's necessary to discard the time information, so if you want something like 25.06.2014 - 01.01.2010 = 1636
, this should work regardless of the DST:
private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd.MM.yyyy");
public static long getDayCount(String start, String end) {
long diff = -1;
try {
Date dateStart = simpleDateFormat.parse(start);
Date dateEnd = simpleDateFormat.parse(end);
//time is always 00:00:00, so rounding should help to ignore the missing hour when going from winter to summer time, as well as the extra hour in the other direction
diff = Math.round((dateEnd.getTime() - dateStart.getTime()) / (double) 86400000);
} catch (Exception e) {
//handle the exception according to your own situation
}
return diff;
}
As the time is always 00:00:00
, using double and then Math.round()
should help to ignore the missing 3600000 ms (1 hour) when going from winter to summer time, as well as the extra hour if going from summer to winter.
This is a small JUnit4 test I use to prove it:
@Test
public void testGetDayCount() {
String startDateStr = "01.01.2010";
GregorianCalendar gc = new GregorianCalendar(locale);
try {
gc.setTime(simpleDateFormat.parse(startDateStr));
} catch (Exception e) {
}
for (long i = 0; i < 10000; i++) {
String dateStr = simpleDateFormat.format(gc.getTime());
long dayCount = getDayCount(startDateStr, dateStr);
assertEquals("dayCount must be equal to the loop index i: ", i, dayCount);
gc.add(GregorianCalendar.DAY_OF_YEAR, 1);
}
}
... or if you want to see what it does 'life', replace the assertion with just:
System.out.println("i: " + i + " | " + dayCount + " - getDayCount(" + startDateStr + ", " + dateStr + ")");
... and this is what the output should look like:
i: 0 | 0 - getDayCount(01.01.2010, 01.01.2010)
i: 1 | 1 - getDayCount(01.01.2010, 02.01.2010)
i: 2 | 2 - getDayCount(01.01.2010, 03.01.2010)
i: 3 | 3 - getDayCount(01.01.2010, 04.01.2010)
...
i: 1636 | 1636 - getDayCount(01.01.2010, 25.06.2014)
...
i: 9997 | 9997 - getDayCount(01.01.2010, 16.05.2037)
i: 9998 | 9998 - getDayCount(01.01.2010, 17.05.2037)
i: 9999 | 9999 - getDayCount(01.01.2010, 18.05.2037)
here's a small program which may help you:
import java.util.*;
public class DateDifference {
public static void main(String args[]){
DateDifference difference = new DateDifference();
}
DateDifference() {
Calendar cal1 = new GregorianCalendar();
Calendar cal2 = new GregorianCalendar();
cal1.set(2010, 12, 1);
cal2.set(2011, 9, 31);
System.out.println("Days= "+daysBetween(cal1.getTime(),cal2.getTime()));
}
public int daysBetween(Date d1, Date d2) {
return (int)( (d2.getTime() - d1.getTime()) / (1000 * 60 * 60 * 24));
}
}
// http://en.wikipedia.org/wiki/Julian_day
public static int julianDay(int year, int month, int day) {
int a = (14 - month) / 12;
int y = year + 4800 - a;
int m = month + 12 * a - 3;
int jdn = day + (153 * m + 2)/5 + 365*y + y/4 - y/100 + y/400 - 32045;
return jdn;
}
public static int diff(int y1, int m1, int d1, int y2, int m2, int d2) {
return julianDay(y1, m1, d1) - julianDay(y2, m2, d2);
}
I'm really really REALLY new at Java, so i'm sure that there's an even better way to do what i'm proposing.
I had this same demand and i did it using the difference between the DAYOFYEAR of the two dates. It seemed an easier way to do it...
I can't really evaluate this solution in performance and stability terms, but i think it's ok.
here:
public static void main(String[] args) throws ParseException { //Made this part of the code just to create the variables i'll use. //I'm in Brazil and the date format here is DD/MM/YYYY, but wont be an issue to you guys. //It will work anyway with your format. String s1 = "18/09/2014"; String s2 = "01/01/2014"; DateFormat f = DateFormat.getDateInstance(); Date date1 = f.parse(s1); Date date2 = f.parse(s2); //Here's the part where we get the days between two dates. Calendar day1 = Calendar.getInstance(); Calendar day2 = Calendar.getInstance(); day1.setTime(date1); day2.setTime(date2); int daysBetween = day1.get(Calendar.DAY_OF_YEAR) - day2.get(Calendar.DAY_OF_YEAR); //Some code just to show the result... f = DateFormat.getDateInstance(DateFormat.MEDIUM); System.out.println("There's " + daysBetween + " days between " + f.format(day1.getTime()) + " and " + f.format(day2.getTime()) + "."); }
In this case, the output would be (remembering that i'm using the Date Format DD/MM/YYYY):
There's 260 days between 18/09/2014 and 01/01/2014.
This function is good for me:
public static int getDaysCount(Date begin, Date end) {
Calendar start = org.apache.commons.lang.time.DateUtils.toCalendar(begin);
start.set(Calendar.MILLISECOND, 0);
start.set(Calendar.SECOND, 0);
start.set(Calendar.MINUTE, 0);
start.set(Calendar.HOUR_OF_DAY, 0);
Calendar finish = org.apache.commons.lang.time.DateUtils.toCalendar(end);
finish.set(Calendar.MILLISECOND, 999);
finish.set(Calendar.SECOND, 59);
finish.set(Calendar.MINUTE, 59);
finish.set(Calendar.HOUR_OF_DAY, 23);
long delta = finish.getTimeInMillis() - start.getTimeInMillis();
return (int) Math.ceil(delta / (1000.0 * 60 * 60 * 24));
}
My best solution (so far) for calculating the number of days difference:
// This assumes that you already have two Date objects: startDate, endDate
// Also, that you want to ignore any time portions
Calendar startCale=new GregorianCalendar();
Calendar endCal=new GregorianCalendar();
startCal.setTime(startDate);
endCal.setTime(endDate);
endCal.add(Calendar.YEAR,-startCal.get(Calendar.YEAR));
endCal.add(Calendar.MONTH,-startCal.get(Calendar.MONTH));
endCal.add(Calendar.DATE,-startCal.get(Calendar.DATE));
int daysDifference=endCal.get(Calendar.DAY_OF_YEAR);
Note, however, that this assumes less than a year's difference!
If you're sick of messing with java you can just send it to db2 as part of your query:
select date1, date2, days(date1) - days(date2) from table
will return date1, date2 and the difference in days between the two.
精彩评论