Java subtract two dates in this format [duplicate] - java

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Calculating difference in dates in Java
How do you subtract Dates in Java?
I am parsing two dates from a string that look like:
Oct 15, 2012 1:07:13 PM
Oct 23, 2012 03:43:34 PM
What I need to do is find the difference between these two dates, ex:
Oct 23, 2012 03:43:34 PM - Oct 15, 2012 1:07:13 PM
= 8 days 2 hours 36 minutes 21 seconds
^ This is what I need to get with the two date/times I have
I believe I need to parse the format and convert it to another format, then subtract the difference between and do the math to get the days/hours/minutes/seconds between

In contrary to what other answerers try to imply, calculating the difference between two dates isn't that trivial in standard Java SE.
Your first step is indeed to convert those strings to useable Date instances. You can do this using SimpleDateFormat. Here's a kickoff example:
String string1 = "Oct 15, 2012 1:07:13 PM";
String string2 = "Oct 23, 2012 03:43:34 PM";
SimpleDateFormat sdf = new SimpleDateFormat("MMM d, yyyy h:mm:ss a", Locale.ENGLISH);
Date date1 = sdf.parse(string1);
Date date2 = sdf.parse(string2);
(please note the importance of the optional Locale argument here, this is often overlooked in answers about converting strings to dates)
Your next step is calculating the difference between those 2 dates. This is a terrible job when you are restricted to the standard Java SE API. Best what you can get is the java.util.Calendar.
Note that you could of course substract the milliseconds and calculate the difference using the usual arithmetic operators.
long differenceInMillis = date2.getTime() - date1.getTime();
// ...
But this naive approach doesn't take leap years into account, let alone daylight saving time and local-specific changes in datetime.
As to the java.util.Calendar approach, you basically need to use Calendar#add() in a counter loop to get the elapsed value for years, months and days. This takes leap years, daylight saving time and local-specific disturbances in time properly into account.
First create this helper method to eliminate some boilerplate code:
public static int elapsed(Calendar before, Calendar after, int field) {
Calendar clone = (Calendar) before.clone(); // Otherwise changes are been reflected.
int elapsed = -1;
while (!clone.after(after)) {
clone.add(field, 1);
elapsed++;
}
return elapsed;
}
Now you can calculate the elapsed time as follows:
Calendar start = Calendar.getInstance();
start.setTime(date1);
Calendar end = Calendar.getInstance();
end.setTime(date2);
Integer[] elapsed = new Integer[6];
Calendar clone = (Calendar) start.clone(); // Otherwise changes are been reflected.
elapsed[0] = elapsed(clone, end, Calendar.YEAR);
clone.add(Calendar.YEAR, elapsed[0]);
elapsed[1] = elapsed(clone, end, Calendar.MONTH);
clone.add(Calendar.MONTH, elapsed[1]);
elapsed[2] = elapsed(clone, end, Calendar.DATE);
clone.add(Calendar.DATE, elapsed[2]);
elapsed[3] = (int) (end.getTimeInMillis() - clone.getTimeInMillis()) / 3600000;
clone.add(Calendar.HOUR, elapsed[3]);
elapsed[4] = (int) (end.getTimeInMillis() - clone.getTimeInMillis()) / 60000;
clone.add(Calendar.MINUTE, elapsed[4]);
elapsed[5] = (int) (end.getTimeInMillis() - clone.getTimeInMillis()) / 1000;
System.out.format("%d years, %d months, %d days, %d hours, %d minutes, %d seconds", elapsed);
Pretty ugly, yeah.
If you going to work with date and time in Java pretty often, then you may find Joda time the walhalla. Here's a concrete kickoff example of how you could do it all with pure Joda Time:
String string1 = "Oct 15, 2012 1:07:13 PM";
String string2 = "Oct 23, 2012 03:43:34 PM";
DateTimeFormatter dtf = DateTimeFormat.forPattern("MMM d, yyyy h:mm:ss a").withLocale(Locale.ENGLISH);
DateTime dateTime1 = dtf.parseDateTime(string1);
DateTime dateTime2 = dtf.parseDateTime(string2);
Period period = new Period(dateTime1, dateTime2);
PeriodFormatter formatter = new PeriodFormatterBuilder()
.appendYears().appendSuffix(" years ")
.appendMonths().appendSuffix(" months ")
.appendWeeks().appendSuffix(" weeks ")
.appendDays().appendSuffix(" days ")
.appendHours().appendSuffix(" hours ")
.appendMinutes().appendSuffix(" minutes ")
.appendSeconds().appendSuffix(" seconds ")
.printZeroNever()
.toFormatter();
String elapsed = formatter.print(period);
System.out.println(elapsed);
Much better, right? The plural "s" needs some work though, but that's beyond the question.

You need to use SimpleDateFormat to parse String and create Date
Then you can find the difference between dates.
Here is javadoc for SimpleDateFormat

try this:
Calendar ca1 = Calendar.getInstance();
ca1.set(2012,05,25);
// Addition of date in java
ca1.add(Calendar.DATE, 23); // Add 23 days in Dates in Calendar
ca1.add(Calendar.MONTH, 2); // Add 2 Month in Date in Calendar
ca1.add(Calendar.YEAR, 4); // add 4 Year in Date in Calendar
ca1.add(Calendar.DATE, -23); // sub 23 days in Dates in Calendar
ca1.add(Calendar.MONTH, -2); // sub 2 Month in Date in Calendar
ca1.add(Calendar.YEAR, -4); // sub 4 Year in Date in Calendar

Related

Why does the difference between 30 March and 1 March 2020 erroneously give 28 days instead of 29?

TimeUnit.DAYS.convert(
Math.abs(
new SimpleDateFormat("dd-MM-yyyy HH:mm:ss").parse("30-03-2020 00:00:00").getTime() -
new SimpleDateFormat("dd-MM-yyyy HH:mm:ss").parse("1-03-2020 00:00:00").getTime()
),
TimeUnit.MILLISECONDS)
The result is 28, while it should be 29.
Could the time zone/location be the problem?
The problem is that because of Daylight Saving Time shift (on Sunday, March 8, 2020), there are 28 days and 23 hours between those dates. TimeUnit.DAYS.convert(...) truncates the result to 28 days.
To see the problem (I'm in US Eastern time zone):
SimpleDateFormat fmt = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
long diff = fmt.parse("30-03-2020 00:00:00").getTime() -
fmt.parse("1-03-2020 00:00:00").getTime();
System.out.println(diff);
System.out.println("Days: " + TimeUnit.DAYS.convert(Math.abs(diff), TimeUnit.MILLISECONDS));
System.out.println("Hours: " + TimeUnit.HOURS.convert(Math.abs(diff), TimeUnit.MILLISECONDS));
System.out.println("Days: " + TimeUnit.HOURS.convert(Math.abs(diff), TimeUnit.MILLISECONDS) / 24.0);
Output
2502000000
Days: 28
Hours: 695
Days: 28.958333333333332
To fix, use a time zone that doesn't have DST, e.g. UTC:
SimpleDateFormat fmt = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
fmt.setTimeZone(TimeZone.getTimeZone("UTC"));
long diff = fmt.parse("30-03-2020 00:00:00").getTime() -
fmt.parse("1-03-2020 00:00:00").getTime();
Output
2505600000
Days: 29
Hours: 696
Days: 29.0
The cause of this problem is already mentioned in Andreas's answer.
The question is what exactly you want to count. The fact that you state that the actual difference should be 29 instead of 28, and ask whether "location/zone time could be a problem", reveals what you actually want to count. Apparently, you want to get rid of any timezone difference.
I assume you only want to calculate the days, without time and timezone.
Java 8
Below, in the example of how the number of days between could be calculated correctly, I'm using a class that represents exactly that – a date without time and timezone – LocalDate.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d-MM-yyyy HH:mm:ss");
LocalDate start = LocalDate.parse("1-03-2020 00:00:00", formatter);
LocalDate end = LocalDate.parse("30-03-2020 00:00:00", formatter);
long daysBetween = ChronoUnit.DAYS.between(start, end);
Note that ChronoUnit, DateTimeFormatter and LocalDate require at least Java 8, which is not available to you, according to the java-7 tag. However, it perhaps is to future readers.
As mentioned by Ole V.V., there's also the ThreeTen Backport, which backports Java 8 Date and Time API functionality to Java 6 and 7.

How to check if the given time falls in mentioned time range

I want to check if my Date value from -
Date d = convertCurrentTimeToSpecificTimeZone("America/Chicago", 2, 30);
falls in the range of 10am to 6 pm.
I found some similar links on StackOverflow similar question and used some of the code from this thread.
All I want to check if the current time from any timezone falls under the range of 10 am to 6 pm. If Yes, print "yes" else print "no".
Currently for below code:
String string1 = "10:11:13";
Date time1 = new SimpleDateFormat("HH:mm:ss").parse(string1);
Calendar calendar1 = Calendar.getInstance();
calendar1.setTime(time1);
calendar1.add(Calendar.DATE, 1);
System.out.println(calendar1.getTime().toString());
It just prints the 10:11 am time of 1970 year. Like this - Fri Jan 02 10:11:13 IST 1970.
But I want to check if today's or any future date time falls in the range of 10 am to 6pm.
Below is the code reference:
public static Date convertCurrentTimeToSpecificTimeZone(String timeZone, int increaseDateBy,
int increaseMinutesBy) {
Calendar calendar = Calendar.getInstance();
TimeZone fromTimeZone = calendar.getTimeZone();
TimeZone toTimeZone = TimeZone.getTimeZone(timeZone);
calendar.setTimeZone(fromTimeZone);
calendar.add(Calendar.MILLISECOND, fromTimeZone.getRawOffset() * -1);
if (fromTimeZone.inDaylightTime(calendar.getTime())) {
calendar.add(Calendar.MILLISECOND, calendar.getTimeZone().getDSTSavings() * -1);
}
calendar.add(Calendar.MILLISECOND, toTimeZone.getRawOffset());
if (toTimeZone.inDaylightTime(calendar.getTime())) {
calendar.add(Calendar.MILLISECOND, toTimeZone.getDSTSavings());
}
increaseCalenderDateBy(calendar, increaseDateBy);
increaseCalenderMinuteBy(calendar, increaseMinutesBy);
return calendar.getTime();
}
public static void getTimeBetweenRange() throws ParseException {
String string1 = "10:11:13";
Date time1 = new SimpleDateFormat("HH:mm:ss").parse(string1);
Calendar calendar1 = Calendar.getInstance();
calendar1.setTime(time1);
calendar1.add(Calendar.DATE, 1);
System.out.println(calendar1.getTime().toString());
String string2 = "18:49:00";
Date time2 = new SimpleDateFormat("HH:mm:ss").parse(string2);
Calendar calendar2 = Calendar.getInstance();
calendar2.setTime(time2);
calendar2.add(Calendar.DATE, 1);
System.out.println(calendar2.getTime().toString());
Date d = convertCurrentTimeToSpecificTimeZone("America/Chicago", 2, 30);
Calendar calendar3 = Calendar.getInstance();
calendar3.setTime(d);
System.out.println(calendar3.getTime().toString());
Date x = calendar3.getTime();
if (x.after(calendar1.getTime()) && x.before(calendar2.getTime())) {
// checkes whether the current time is between 14:49:00 and 20:11:13.
System.out.println(true);
} else
System.out.println(false);
}
So the output for my below code is:
Fri Jan 02 10:11:13 IST 1970
Fri Jan 02 18:49:00 IST 1970
Fri Jan 31 03:15:07 IST 2020
It’s not very clear. For this answer I am assuming that all of your times are to be understood in America/Chicago time zone. Please revert if this was not what you intended.
java.time
ZoneId zone = ZoneId.of("America/Chicago");
ZonedDateTime zdt = ZonedDateTime.now(zone).plusDays(2).plusMinutes(30);
LocalTime rangeStart = LocalTime.parse("10:11:13");
LocalTime rangeEnd = LocalTime.parse("18:49:00");
LocalTime time = zdt.toLocalTime();
if (!time.isBefore(rangeStart) && time.isBefore(rangeEnd)) {
System.out.println("Yes");
} else {
System.out.println("No");
}
When I ran this code snippet just now (at 11:30 Chicago time), the output was:
Yes
I am using java.time, the modern Java date and time API, and recommend that you do the same. It’s so much nicer to work with than the old, outdated and poorly designed classes Date, SimpleDateFormat, Calendar and TimeZone.
A LocalTime is a time of day from 00:00 (inclusive) to 24:00 (exclusive). By comparing LocalTimeobjects we are ignoring the date and have no trouble with irrelevant dates in 1970 or some other time in history.
Edit:
Also is it possible to get the date and time of rangeStart and
rangeEnd in order to verify for which particular day and time we are
checking the conditions?
No, that would not make sense. Since a LocalTime is a time of day without date, there is no way to get a date out of it. But you can print the ZonedDateTime and verify its date part. And to assure yourself that the code is correct, write some unit tests.
Link: Oracle tutorial: Date Time explaining how to use java.time.
A simple approach might be to parse your time Strings to instances of LocalTime and compare them. You have to decide if the start and end time are inclusive or not...
Support some formattings because you might have to pass Strings with AM/PM or without:
public static boolean isInTimeSlot(String time, String timeSlotStart, String timeSlotEnd) {
// create a formatter that supports different formats for the String arguments
DateTimeFormatter parserDtf = DateTimeFormatter.ofPattern("[hh:mm:ss a][HH:mm:ss][h a]");
// parse each argument to a LocalTime
LocalTime timeOfDay = LocalTime.parse(time, parserDtf);
LocalTime fromTime = LocalTime.parse(timeSlotStart, parserDtf);
LocalTime toTime = LocalTime.parse(timeSlotEnd, parserDtf);
// and return if the given time is in the time slot (including start and end time)
return timeOfDay.equals(fromTime) || timeOfDay.equals(toTime)
|| (timeOfDay.isAfter(fromTime) && timeOfDay.isBefore(toTime));
}
If you run it in a main like this
public static void main(String[] args) {
// provide some sample times
String[] times = { "10:31:17", "09:59:59", "6 PM", "4 AM", "06:00:01 PM" };
// provide a time slot
String from = "10 AM";
String to = "6 PM";
// check the method for each time string
for (String time : times) {
if (isInTimeSlot(time, from, to)) {
System.out.println(time + " is in the time slot at or between "
+ from + " and " + to);
} else {
System.err.println(time + " is not in the time slot at or between "
+ from + " and " + to);
}
}
}
the output will be
10:31:17 is in the time slot at or between 10 AM and 6 PM
09:59:59 is not in the time slot at or between 10 AM and 6 PM
6 PM is in the time slot at or between 10 AM and 6 PM
4 AM is not in the time slot at or between 10 AM and 6 PM
06:00:01 PM is not in the time slot at or between 10 AM and 6 PM
All I want to check if the current time from any timezone falls under the range of 10 am to 6 pm. If Yes, print "yes" else print "no".
For this, the following code will do the job.
LocalTime lt = LocalTime.now();
if( lt.isAfter( LocalTime.of( 10, 0 ) ) && lt.isBefore( LocalTime.of( 18, 0 ) ) ) System.out.println( "Yes" );
else System.out.println( "No" );
Since you have Date instances with you, you can convert them into LocalTime instances as shown below and use the same mechanism of comparison.
Date d = new Date(); //Change this to your way of creating the Date instance
LocalTime lt = LocalDateTime.ofEpochSecond( d.getTime(), 0, ZoneOffset.ofHours( 0 ) ).toLocalTime();
Hope this helps.

How do I get the String type or timestamp type by giving a year

there is a requirement to get the startTime and endTime around the whole year by giving a int year, for example, given a variable int year = 2017, I want to get the starttime String "2017-01-01 00:00:00" and endtime String "2017-12-31 23:59:59", or get the starttime timestamp 1483200000 and endtime timestamp 1514735999. 2 results are ok to us, How should I do by java8 or below? I have known:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String datetime = sdf.format(new Date(*timestamp*))
but I have no idea how I can get the timestamp by the given year, please help to check
int year = 2017;
// Using LocalDateTime (Java 8+ or Java 6+ with ThreeTen backport)
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
String start1 = LocalDateTime.of(year, Month.JANUARY, 1, 0, 0).format(dtf);
String stop1 = LocalDateTime.of(year, Month.DECEMBER, 31, 23, 59, 59).format(dtf);
System.out.println(start1 + " - " + stop1);
// Using Calendar (antiquated)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Calendar cal = Calendar.getInstance();
cal.clear();
cal.set(year, Calendar.JANUARY, 1);
String start2 = sdf.format(cal.getTime());
cal.set(year, Calendar.DECEMBER, 31, 23, 59, 59);
String stop2 = sdf.format(cal.getTime());
System.out.println(start2 + " - " + stop2);
Output
2017-01-01 00:00:00 - 2017-12-31 23:59:59
2017-01-01 00:00:00 - 2017-12-31 23:59:59
Use a half-open interval
As Basil Bourque said in a comment: use a half-open interval. That is, define year 2017 as the time from the first moment of 2017 inclusive to the first moment of 2018 exclusive. So any moment that is on or after the start time and strictly before the end time belongs to the year.
Philosophical argument: It saves us from deciding whether to run up to the last second, the last millisecond or the last nanosecond of the year. An even if we rook the last nano, we would still have excluded a full nano from the year, which is incorrect. Yes, I know, your application only needs a granularity of seconds, so “it doesn’t matter”. But what if the next version does require a finer granularity? And even if it won’t, you should not want to fill errors or inaccuracies into your program, not even when the user doesn’t see any symptom of them.
Practical argument: A half-open interval simplifies some things, both when calculating the timestamps and when applying them.
ZoneId zone = ZoneId.of("Asia/Singapore");
Year year = Year.of(2017);
long startTime = year.atDay(1).atStartOfDay(zone).toEpochSecond();
System.out.println(startTime);
long endTime = year.plusYears(1).atDay(1).atStartOfDay(zone).toEpochSecond();
System.out.println(endTime);
Output from this snippet is:
1483200000
1514736000
If you absolutely insist, you may of course subtract 1 from the latter number.
Notice that using atStartOfDay() also saves us from assuming that the day begins at 00:00:00 and ends a second after 23:59:59. Funny time anomalies may cause this not to be the case. Such anomalies are in the time zone database and Java takes them into account when we just query the start of day in a time zone.
You can do like this using java.sql.Timestamp
import java.util.Date;
import java.sql.Timestamp;
public class Main
{
public static void main( String[] args )
{
Date date= new Date();
long time = date.getTime();
System.out.println("Time (Milliseconds): " + time);
Timestamp ts = new Timestamp(time);
System.out.println("Current Time Stamp: " + ts);
}
}
Using Java 8 only:
int year = 2017;
// using one of the predefined format from enum java.time.format.FormatStyle
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG);
LocalDateTime beginDate = LocalDateTime.of(year, Month.JANUARY, 1, 0, 0, 0);
LocalDateTime endDate = LocalDateTime.of(year, Month.DECEMBER, 31, 23, 59, 59);
String beginDateFormatted = beginDate.format(formatter);
String endDateFormatted = endDate.format(formatter);
long beginTimestamp = this.beginDate.toInstant(ZoneOffset.UTC).toEpochMilli();
long endTimestamp = this.endDate.toInstant(ZoneOffset.UTC).toEpochMilli();
Check working example here.

Subtracting two dates in Java

I want to subtract two dates (one constant and one current) in Java but I've got strange problems with it. Here is the code :
DateFormat df = new SimpleDateFormat("HH:MM");
Date FirstLessonInterval=df.parse("08:45");
Date currentTime = new Date();
long diff = FirstLessonInterval.getTime()-currentTime.getTime();
String s = String.valueOf(diff);
LessonOrBreak=(diff);
I've got minus minutes. When I want to see FirstLessonInterval with FirstLessonInterval.toString() it shows the year 1970. What can I do?
You forgot to give a date, you just defined a time:
DateFormat df = new SimpleDateFormat("HH:MM");
Date FirstLessonInterval=df.parse("08:45");
and this is in unix time day 0 which is the 1.1.1970
try something like
DateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:MM");
Date FirstLessonInterval=df.parse("2014/05/10 08:45");
1970 is where all time began according to computers. Are we missing some code in your question? You can faff around with the current time in milliseconds but i'd take a look at JodaTime and use that.
The reason you are getting 1970.... is because I suspect your diff is quite a small number. Then if you look at that as a date then it will be a small number + 1 Jan 1970 which will still be in 1970. But as i said I suspect we are missing some code in your question.
In JodaTime you can do somethign like the below but im not sure what it is you are exactly after
Interval i= new Interval(new DateTime(FirstLessonInterval), new DateTime());
System.out.println("Interval is: " + i.toDurationMillis());
Your format pattern is incorrect, use lower case mm to represent minutes
When you do not specify much details to the outdated Java date api, it considers the time since UNIX epoch (1st Jan 1970)
Since you are assuming the date to be the same as the constant time parameters you provide and independent of the timezones, you can bring your current date comparable to the time since UNIX epoch:
Staying close to your original code;
DateFormat df = new SimpleDateFormat("HH:mm");
Date firstLessonInterval = df.parse("08:45");
Date currentTime = new Date();
// Format the current date comparable to UNIX epoch (only hold time params)
String dateStr = df.format(currentTime.getTime());
// Parse the modified date string to a date object
Date comDate = df.parse(dateStr);
// Take the difference in millis
long diff = firstLessonInterval.getTime() - comDate.getTime();
String s = String.valueOf(diff);
// Print the number of minutes passed since
System.out.println("Minutes {elapsed since/time to} 08:45 - " + Math.abs(diff) / 1000 / 60);
Missing Date Portion
As the other correct answers said, you are using the java.util.Date class which is a date-time class holding both a date portion and a time portion.
LocalTime
If you truly care about only time of day, with no date and no time zone, then use the LocalTime class found in both the Joda-Time library and the new java.tome package in Java 8. By the way the old java.util.Date and .Calendar classes are notoriously troublesome and should be avoided.
Joda-Time
Here is some code with date-time and time zone.
Using the Joda-Time 2.3 library…
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Warsaw" );
DateTime dateTime = new DateTime( 2014, 1, 2, 8, 45, 0, timeZone );
DateTime now = new DateTime( 2014, 1, 2, 8, 30, 0, timeZone ); // Or DateTime.now( timeZone )
Duration duration = new Duration( dateTime, now ); // or use Period or Interval.
Joda-Time offers intelligent classes and methods of working with a span of time (a Period, Interval, or Duration). For example look at the Minutes class. But if all you need is millseconds, here you go.
long millis = duration.getMillis();
The problem is that you are not providing enough info to SimpleDateFormat. It sets the hour and minutes correctly but nothing else.
DateFormat df = new SimpleDateFormat("HH:mm");
System.out.println(df.parse("08:45")); // Thu Jan 01 08:45:00 GMT 1970
System.out.println(new Date()); // Sun May 11 07:52:50 GMT 2014
If you want your date to be with respect to the current date try this:
Date curr = new Date();
Date date = new Date(curr.getYear(),
curr.getMonth(),
curr.getDate(),
8, 45, 0);
System.out.println(date); // Sun May 11 08:45:00 GMT 2014
System.out.println(curr); // Sun May 11 07:52:50 GMT 2014
long diff = date.getTime() - curr.getTime();
System.out.println("Minutes: " + diff/6000); // Minutes: 53
I dont know if this way is efficient or not but it's an idea anyway:
Date curr = new Date();
Date date = new Date(114, /*114 is 2014 , don't know why*/
6,
16,
8, 45, 0);
System.out.println(curr);
System.out.println(date);
Date x = new Date(curr.getYear() - date.getYear() ,
curr.getMonth() - date.getMonth(),
curr.getDate() - date.getDate(),
curr.getHours() - date.getHours(),
curr.getMinutes() - date.getMinutes(),
curr.getSeconds() - date.getSeconds() );
String startDateString = "2017-03-08";
String finishDateString = "2017-03-10";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.ENGLISH);
LocalDate startDate = LocalDate.parse(startDateString, formatter);
LocalDate finishDate = LocalDate.parse(finishDateString, formatter);
Integer day = finishDate.compareTo(startDate);
Integer day will be 3. It means that the difference between two dates equals 3 days

Get Previous Day [duplicate]

This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
How to determine the date one day prior to a given date in Java?
If I have a Java.Util.Date object, what is the best way to get an object representing the 24 hours in the past of it?
Using Java 1.6 java.util.Calendar.add:
public static Date subtractDay(Date date) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.DAY_OF_MONTH, -1);
return cal.getTime();
}
Others suggest using Joda Time, which is currently JSR 310, and should later be included in Java itself.
The important thing to remember is that the Date class should represent any points in time whilst the Calendar class is used to manipulate those points in time. Last of all, SimpleDateFormat will represent them as Strings.
So, the best way is to use the Calendar class to calculate the new Date for you. This will ensure that any vagaries (Daylight Saving, Leap Years and the like) are accounted for.
I'm assuming that you don't really want to find '24 Hours previous' but actually do want a new Date instance representing 'this time yesterday' - either way, you can ask the Calendar instance for a Date 24Hours prior to another or 1 Day prior.
The Daylight savings is a great example. The UK 'sprang forward' on the 26th March 2009. So, 1 day prior to 3.00a.m. on the 26.Mar.2009 should yield 3.00a.m. 25.Mar.2009 but 24 Hrs prior will yield 2.00a.m.
public class DateTests extends TestCase {
private static String EXPECTED_SUMMER_TIME = "2009.Mar.29 03:00:00";
private static String EXPECTED_SUMMER_TIME_LESS_DAY = "2009.Mar.28 03:00:00";
private static String EXPECTED_SUMMER_TIME_LESS_24_HRS = "2009.Mar.28 02:00:00";
private static String EXPECTED_SUMMER_TIME_LESS_FURTHER_24_HRS = "2009.Mar.27 02:00:00";
public void testSubtractDayOr24Hours() {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy.MMM.dd HH:mm:SS");
Calendar calendar = Calendar.getInstance();
// Create our reference date, 3.00 a.m. on the day the clocks go forward (they 'went' forward at 02.00)
calendar.clear();
calendar.set(2009, 2, 29, 3, 0);
Date summerTime = calendar.getTime(); // Sun Mar 29 03:00:00 BST 2009
String formattedSummerTime = formatter.format(summerTime);
calendar.add(Calendar.DAY_OF_MONTH, -1);
// Our reference date less 'a day'
Date summerTimeLessADay = calendar.getTime(); // Sat Mar 28 03:00:00 GMT 2009
String formattedSummerTimeLessADay = formatter.format(summerTimeLessADay);
// reset the calendar instance to the reference day
calendar.setTime(summerTime);
// Our reference date less '24 hours' (is not quite 24 hours)
calendar.add(Calendar.HOUR, -24);
Date summerTimeLess24Hrs = calendar.getTime(); // Sat Mar 28 02:00:00 GMT 2009
String formattedSummerTimeLess24Hrs = formatter.format(summerTimeLess24Hrs);
// Third date shows that taking a further 24 hours from yields expected result
calendar.add(Calendar.HOUR, -24);
Date summerTimeLessFurther24Hrs = calendar.getTime(); // Fri Mar 27 02:00:00 GMT 2009
String formattedSummerTimeLessFurther24Hrs = formatter.format(summerTimeLessFurther24Hrs);
// reset the calendar once more to the day before
calendar.setTime(summerTimeLess24Hrs);
// Take a 'day' from the Sat will yield the same result as date 03 because Daylight Saving is not a factor
calendar.add(Calendar.DAY_OF_MONTH, -1);
Date summerTimeLessFurtherDay = calendar.getTime(); // Fri Mar 27 02:00:00 GMT 2009
String formattedSummerTimeLessFurtherDay = formatter.format(summerTimeLessFurtherDay);
assert(formattedSummerTime.equals(EXPECTED_SUMMER_TIME));
assert(formattedSummerTimeLessADay.equals(EXPECTED_SUMMER_TIME_LESS_DAY));
assert(formattedSummerTimeLess24Hrs.equals(EXPECTED_SUMMER_TIME_LESS_24_HRS));
assert(formattedSummerTimeLessFurther24Hrs.equals(EXPECTED_SUMMER_TIME_LESS_FURTHER_24_HRS));
// This last test proves that taking 24 hors vs. A Day usually yields the same result
assert(formattedSummerTimeLessFurther24Hrs.equals(formattedSummerTimeLessFurtherDay));
}
}
For testing date functions, wwwdot-timeanddate-dot-com is a great resource.
subtract 1000*60*60*24 from the time and create a new date.
Date yesterday = new Date(d.getTime() - (1000*60*60*24));
int dayInMs = 1000 * 60 * 60 * 24;
Date previousDay = new Date(olddate.getTime() - dayInMs);
Personally if there are a lot of time/date calculations, I'd go with Joda-time.

Categories