Wrong value of Days between two Dates - java

I'm trying to count the days between two dates but I can't get a right result.
I did the same that someone described to me.
My result should be an int or long. For this example I would expext 11 but 10 is also fine.
That's the code:
String startDate = "2018-03-25";
String endDate = "2018-04-05";
Date startDate1 = stringToDate(startDate);
Date endDate1 = stringToDate(endDate);
long ab = daysBetween(startDate1, endDate1);
String ab1 = String.valueOf(ab);
And that's the methods:
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;
}
public Date stringToDate(String stringDatum) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
try {
Date date = format.parse(stringDatum);
return date;
}
catch (ParseException e) {
e.printStackTrace();
}
return null;
}
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
}

java.util.Date, Calendar and SimpleDateFormat are part of a terrible API. They make the job of date/time handling harder than it already is.
Make yourself a favor and use a decent date/time library: https://github.com/JakeWharton/ThreeTenABP - here's a nice tutorial on how to use it - How to use ThreeTenABP in Android Project
With this API, it's so easy to do what you want:
LocalDate startDate = LocalDate.parse("2018-03-25");
LocalDate endDate = LocalDate.parse("2018-04-05");
long daysBetween = ChronoUnit.DAYS.between(startDate, endDate); // 11
I've chosen to use LocalDate based on your code: the inputs have only day, month and year, and you're setting the hour/minute/seconds to zero, so I understand that you don't care about the time of the day to calculate the difference - which makes LocalDate the best choice.
Date and Calendar represent a specific point in time, and Calendar also uses a timezone, so Daylight Saving changes might affect the results, depending on the device's default timezone. Using a LocalDate avoids this problem, because this class doesn't have a timezone.
But anyway, I've tested your code and also got 11 as result, so it's not clear what problems you're facing.

private static long daysBetween(Date date1, Date date2){
return (date2.getTime() - date1.getTime()) / (60*60*24*1000);
}

Related

Combine two type dates into one

I have two type dates that I get from my database :
Date : 2017-01-28 || Time : 12:59
And I want to combine it into a one Date variable.
this is the origin of the two variables :
#Temporal(value = TemporalType.DATE)
#Future
#DateTimeFormat(pattern = "dd/MM/YY")
#Column(name = "dateDebut", nullable = true)
private Date date;
#Temporal(TemporalType.TIME)
#Column(name="Start_Hour")
private Date startHour;
any help will be appreciated.Thank you.
Use a Calendar object:
private static Date combine(Date date, Date time) {
Calendar cal = Calendar.getInstance();
cal.setTime(time);
int hour = cal.get(Calendar.HOUR_OF_DAY);
int min = cal.get(Calendar.MINUTE);
cal.setTime(date);
cal.set(Calendar.HOUR_OF_DAY, hour);
cal.set(Calendar.MINUTE, min);
return cal.getTime();
}
Test
Date date = new SimpleDateFormat("yyyy-MM-dd").parse("2017-01-28");
Date startHour = new SimpleDateFormat("HH:mm").parse("12:59");
System.out.println(combine(date, startHour));
Output
Sat Jan 28 12:59:00 EST 2017
Now you need to do some conversions of your date and hour, you may as well convert them to one of the Java 8 date and time classes — provided you can use Java 8, of course. These classes are much nicer to work with downstream than the old-fashioned Date class. It’s even more straightforward than the other answers. For example:
LocalDate d = date.toInstant().atZone(ZoneOffset.systemDefault()).toLocalDate();
LocalTime t = startHour.toInstant().atZone(ZoneOffset.systemDefault()).toLocalTime();
LocalDateTime dt = d.atTime(t);
System.out.println(dt);
This prints:
2017-01-28T12:29
Depending on you requirements, it may be that you’ll prefer to stay with a ZonedDateTime or some other Java 8 type. These classes are quite versatile, so chances are that you can get what you want with few lines of code.
Edit: Some JPA implementations may support the Java 8 date and time classes directly, so you may spare the first two lines and only need the third. See JPA support for Java 8 new date and time API.
I got the idea you wanted to parse a date from that String (as I'm not sure what do you mean by that origin format).
So maybe this will help:
private static final String STRING_TO_FORMAT = "Date : 2017-01-28 || Time : 12:59";
public static void main(String[] args) {
Matcher matcher = Pattern.compile(".*(\\d{4}-\\d{2}-\\d{2}).*(\\d{2}:\\d{2})").matcher(STRING_TO_FORMAT);
matcher.find();
Date date = null;
try {
date = new SimpleDateFormat("yyyy-MM-dd HH:mm").parse(matcher.group(1) + " " + matcher.group(2));
System.out.println(date);
} catch (ParseException e) {
}
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yy HH:mm");
System.out.println(formatter.format(date));
}

Comparing if 2 dates are the same day Java

Good day, quick question, Am trying to compare if 2 dates are the same day for the same time zone (city)Anyone have any idea why the following code holds and the other doesn't, can't seem to understand why.
SimpleDateFormat fmt = new SimpleDateFormat("EEE dd,MMM");
Date newparsetemp = fmt.parse(parsedate);
Date currentdateparse = fmt.parse(currentdate);
if(currentdateparse.equals(newparsetemp)){
//code executes
}
but if i do use this, the if condition doesn't hold
SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
Date newparsetemp = fmt.parse(parsedate);
Date currentdateparse = fmt.parse(currentdate);
if(currentdateparse.equals(newparsetemp)){
//does not
}
Consider using Joda-Time's LocalDate.
Date data1 = ...
Date date2 = ...
new LocalDate(date1).equals(new LocalDate(date2))
Better yet just skip Date and use LocalDate instead.
Comparing after formatting to a string is an odd thing to do. Try this instead:
Calendar cal = GregorianCalendar.getInstance();
cal.setTime(parsedate);
Calendar cal2 = GregorianCalendar.getInstance();
cal2.setTime(currentdate);
cal2.set(Calendar.HOUR, 0);
cal2.set(Calendar.MINUTE, 0);
cal2.set(Calendar.SECOND, 0);
cal2.set(Calendar.MILLISECOND, 0);
cal.set(Calendar.HOUR, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
System.out.println(cal.equals(cal2) ? "true" : "false");
Your comment about timezones needs clarification. Did you mean to say
compare if 2 dates are the same day for different time zones?
If you mean "comparing only the day of week", have you tried comparing the result of Calendar.get(Calendar.DAY_OF_WEEK) instead?
do you agree that there is a chance that two different dates from different years, in the same month and day, can match the same day of the week?
and that there's no chance of two different dates match the same day, month and year?
I've actually done this not too long ago in one of my Android apps,
public boolean isSameDay(Event otherEvent) {
if(otherEvent == null) return false;
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
try {
Calendar otherEventDate = Calendar.getInstance();
otherEventDate.setTime(format.parse(otherEvent.getStartTime()));
Calendar thisEventDate = Calendar.getInstance();
thisEventDate.setTime(format.parse(getStartTime()));
return (otherEventDate.get(Calendar.DAY_OF_MONTH) == thisEventDate.get(Calendar.DAY_OF_MONTH) &&
otherEventDate.get(Calendar.DAY_OF_YEAR) == thisEventDate.get(Calendar.DAY_OF_YEAR));
} catch(ParseException e) {
System.out.println(e.toString());
e.printStackTrace();
}
return false;
}
Here's the code as I did it, I'm just checking if the two events are occurring the same day. If you wish to add some more precision you'll just have to add this for yourself.

How to subtract X day from a Date object in Java?

I want to do something like:
Date date = new Date(); // current date
date = date - 300; // substract 300 days from current date and I want to use this "date"
How to do it?
Java 8 and later
With Java 8's date time API change, Use LocalDate
LocalDate date = LocalDate.now().minusDays(300);
Similarly you can have
LocalDate date = someLocalDateInstance.minusDays(300);
Refer to https://stackoverflow.com/a/23885950/260990 for translation between java.util.Date <--> java.time.LocalDateTime
Date in = new Date();
LocalDateTime ldt = LocalDateTime.ofInstant(in.toInstant(), ZoneId.systemDefault());
Date out = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());
Java 7 and earlier
Use Calendar's add() method
Calendar cal = Calendar.getInstance();
cal.setTime(dateInstance);
cal.add(Calendar.DATE, -30);
Date dateBefore30Days = cal.getTime();
#JigarJoshi it's the good answer, and of course also #Tim recommendation to use .joda-time.
I only want to add more possibilities to subtract days from a java.util.Date.
Apache-commons
One possibility is to use apache-commons-lang. You can do it using DateUtils as follows:
Date dateBefore30Days = DateUtils.addDays(new Date(),-30);
Of course add the commons-lang dependency to do only date subtract it's probably not a good options, however if you're already using commons-lang it's a good choice. There is also convenient methods to addYears,addMonths,addWeeks and so on, take a look at the api here.
Java 8
Another possibility is to take advantage of new LocalDate from Java 8 using minusDays(long days) method:
LocalDate dateBefore30Days = LocalDate.now(ZoneId.of("Europe/Paris")).minusDays(30);
Simply use this to get date before 300 days, replace 300 with your days:
Date date = new Date(); // Or where ever you get it from
Date daysAgo = new DateTime(date).minusDays(300).toDate();
Here,
DateTime is org.joda.time.DateTime;
Date is java.util.Date
Java 8 Time API:
Instant now = Instant.now(); //current date
Instant before = now.minus(Duration.ofDays(300));
Date dateBefore = Date.from(before);
As you can see HERE there is a lot of manipulation you can do. Here an example showing what you could do!
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Calendar cal = Calendar.getInstance();
//Add one day to current date.
cal.add(Calendar.DATE, 1);
System.out.println(dateFormat.format(cal.getTime()));
//Substract one day to current date.
cal = Calendar.getInstance();
cal.add(Calendar.DATE, -1);
System.out.println(dateFormat.format(cal.getTime()));
/* Can be Calendar.DATE or
* Calendar.MONTH, Calendar.YEAR, Calendar.HOUR, Calendar.SECOND
*/
With Java 8 it's really simple now:
LocalDate date = LocalDate.now().minusDays(300);
A great guide to the new api can be found here.
In Java 8 you can do this:
Instant inst = Instant.parse("2018-12-30T19:34:50.63Z");
// subtract 10 Days to Instant
Instant value = inst.minus(Period.ofDays(10));
// print result
System.out.println("Instant after subtracting Days: " + value);
I have created a function to make the task easier.
For 7 days after dateString: dateCalculate(dateString,"yyyy-MM-dd",7);
To get 7 days upto dateString: dateCalculate(dateString,"yyyy-MM-dd",-7);
public static String dateCalculate(String dateString, String dateFormat, int days) {
Calendar cal = Calendar.getInstance();
SimpleDateFormat s = new SimpleDateFormat(dateFormat);
try {
cal.setTime(s.parse(dateString));
} catch (ParseException e) {
e.printStackTrace();
}
cal.add(Calendar.DATE, days);
return s.format(cal.getTime());
}
You may also be able to use the Duration class. E.g.
Date currentDate = new Date();
Date oneDayFromCurrentDate = new Date(currentDate.getTime() - Duration.ofDays(1).toMillis());
You can easily subtract with calendar with SimpleDateFormat
public static String subtractDate(String time,int subtractDay) throws ParseException {
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.ENGLISH);
cal.setTime(sdf.parse(time));
cal.add(Calendar.DATE,-subtractDay);
String wantedDate = sdf.format(cal.getTime());
Log.d("tag",wantedDate);
return wantedDate;
}

Formatting date and time

I have a question related to conversion/formatting of date.
I have a date,say,workDate with a value, eg: 2011-11-27 00:00:00
From an input textbox, I receive a time value(as String) in the form "HH:mm:ss", eg: "06:00:00"
My task is to create a new Date,say,newWorkDate, having the same year,month,date as workDate,and time to be the textbox input value.
So in this case, newWorkDate should be equal to 2011-11-27 06:00:00.
Can you help me figure out how this can be achieved using Java?
Here is what I have so far:
SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
//Text box input is converted to Date format -what will be the default year,month and date set here?
Date textBoxTime = df.parse(minorMandatoryShiftStartTimeStr);
Date workDate = getWorkDate();
int year = Integer.parseInt(DateHelper.getYYYYMMDD(workDate).substring(0, 4));
int month = Integer.parseInt(DateHelper.getYYYYMMDD(workDate).substring(4, 6));
int date = Integer.parseInt(DateHelper.getYYYYMMDD(workDate).substring(6, 8));
Date newWorkDate = DateHelper.createDate(year, month, day);
//not sure how to set the textBox time to this newWorkDate.
[UPDATE]: Thx for the help,guys!Here is the updated code based on all your suggestions..Hopefully this will work.:)
String[] split = textBoxTime.split(":");
int hour = 0;
if (!split[0].isEmpty)){
hour = Integer.parseInt(split[0]);}
int minute = 0;
if (!split[1].isEmpty()){
minute = Integer.parseInt(split[1]);}
int second = 0;
if (!split[2].isEmpty()){
second = Integer.parseInt(split[2]);}
Calendar cal=Calendar.getInstance();
cal.setTime(workDate);
cal.set(Calendar.HOUR, hour);
cal.set(Calendar.MINUTE, minute);
cal.set(Calendar.SECOND, second);
Date newWorkDate = cal.getTime();
A couple of hints:
Use a Calendar object to work with the dates. You can set the Calendar from a Date so the way you create the dates textBoxTime and workDate are fine.
Set the values of workDate from textBoxTime using the setXXX methods on Calendar class (make workDate a Calendar)
You can use SimpleDateFormat to format as well as parse. Use this to produce the desired output.
You should be able to do this with no string parsing and just a few lines of code.
Since you already have the work date, all you need to do is convert your timebox to seconds and add it to your date object.
Use Calendar for date Arithmetic.
Calendar cal=Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.HOUR, hour);
cal.add(Calendar.MINUTE, minute);
cal.add(Calendar.SECOND, second);
Date desiredDate = cal.getTime();
You may need the following code.
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class DateFormat {
public static void main(String[] args) {
try {
SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy-MM-dd");
Date workDate = simpleDateFormat1.parse("2011-11-27");
Calendar workCalendar= Calendar.getInstance();
workCalendar.setTime(workDate);
SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("HH:mm:ss");
Calendar time = Calendar.getInstance();
time.setTime(simpleDateFormat2.parse("06:00:00"));
workCalendar.set(Calendar.HOUR_OF_DAY, time.get(Calendar.HOUR_OF_DAY));
workCalendar.set(Calendar.MINUTE, time.get(Calendar.MINUTE));
workCalendar.set(Calendar.SECOND, time.get(Calendar.SECOND));
Date newWorkDate = workCalendar.getTime();
SimpleDateFormat simpleDateFormat3 = new SimpleDateFormat(
"yyyy-MM-dd hh:mm:ss");
System.out.println(simpleDateFormat3.format(newWorkDate));
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Hope this would help you.

How to get previous date in java

I have a String Object in format yyyyMMdd.Is there a simple way to get a String with previous date in the same format?
Thanks
I would rewrite these answers a bit.
You can use
DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
// Get a Date object from the date string
Date myDate = dateFormat.parse(dateString);
// this calculation may skip a day (Standard-to-Daylight switch)...
//oneDayBefore = new Date(myDate.getTime() - (24 * 3600000));
// if the Date->time xform always places the time as YYYYMMDD 00:00:00
// this will be safer.
oneDayBefore = new Date(myDate.getTime() - 2);
String result = dateFormat.format(oneDayBefore);
To get the same results as those that are being computed by using Calendar.
Here is how to do it without Joda Time:
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class Main {
public static String previousDateString(String dateString)
throws ParseException {
// Create a date formatter using your format string
DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
// Parse the given date string into a Date object.
// Note: This can throw a ParseException.
Date myDate = dateFormat.parse(dateString);
// Use the Calendar class to subtract one day
Calendar calendar = Calendar.getInstance();
calendar.setTime(myDate);
calendar.add(Calendar.DAY_OF_YEAR, -1);
// Use the date formatter to produce a formatted date string
Date previousDate = calendar.getTime();
String result = dateFormat.format(previousDate);
return result;
}
public static void main(String[] args) {
String dateString = "20100316";
try {
// This will print 20100315
System.out.println(previousDateString(dateString));
} catch (ParseException e) {
System.out.println("Invalid date string");
e.printStackTrace();
}
}
}
You can use:
Calendar cal = Calendar.getInstance();
//subtracting a day
cal.add(Calendar.DATE, -1);
SimpleDateFormat s = new SimpleDateFormat("yyyyMMdd");
String result = s.format(new Date(cal.getTimeInMillis()));
It's much harder than it should be in Java without library support.
You can parse the given String into a Date object using an instance of the SimpleDateFormat class.
Then you can use Calendar's add() to subtract one day.
Then you can use SimpleDateFormat's format() to get the formatted date as a String.
The Joda Time library a much easier API.
This is an old question, and most existing answers pre-date Java 8. Hence, adding this answer for Java 8+ users.
Java 8 introduced new APIs for Date and Time to replace poorly designed, and difficult to use java.util.Date and java.util.Calendar classes.
To deal with dates without time zones, LocalDate class can be used.
String dateString = "20200301";
// BASIC_ISO_DATE is "YYYYMMDD"
// See below link to docs for details
LocalDate date = LocalDate.parse(dateString, DateTimeFormatter.BASIC_ISO_DATE);
// get date for previous day
LocalDate previousDate = date.minusDays(1);
System.out.println(previousDate.format(DateTimeFormatter.BASIC_ISO_DATE));
// prints 20200229
Docs:
DateTimeFormatter.BASIC_ISO_DATE
LocalDate
use SimpleDateFormat to parse the String to Date, then subtract one day. after that convert the date to String again.
HI,
I want to get 20 days previous, to current date,
Calendar cal = Calendar.getInstance();
Calendar xdate = (Calendar)cal.clone();
xdate.set(Calendar.DAY_OF_YEAR, - 20);
System.out.println(" Current Time "+ cal.getTime().toString());
System.out.println(" X Time "+ xdate.getTime().toString());
I had some UN Expected result, When i tried on Jan 11th,
Current Time Tue Jan 11 12:32:16 IST 2011
X Time Sat Dec 11 12:32:16 IST 2010
Calendar cal = Calendar.getInstance();
Calendar xdate = (Calendar)cal.clone();
xdate.set(Calendar.DAY_OF_YEAR,cal.getTime().getDate() - 20 );
System.out.println(" Current Time "+ cal.getTime().toString());
System.out.println(" X Time "+ xdate.getTime().toString());
This code solved my Problem.
If you are willing to use the 3rd-party utility, Joda-Time, here is some example code using Joda-Time 2.3 on Java 7. Takes just two lines.
String dateAsString = "20130101";
org.joda.time.LocalDate someDay = org.joda.time.LocalDate.parse(dateAsString, org.joda.time.format.DateTimeFormat.forPattern("yyyymmdd"));
org.joda.time.LocalDate dayBefore = someDay.minusDays(1);
See the results:
System.out.println("someDay: " + someDay );
System.out.println("dayBefore: " + dayBefore );
When run:
someDay: 2013-01-01
dayBefore: 2012-12-31
This code assumes you have no time zone. Lacking a time zone is rarely a good thing, but if that's your case, that code may work for you. If you do have a time zone, use a DateTime object instead of LocalDate.
About that example code and about Joda-Time…
// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.
// Joda-Time - The popular alternative to Sun/Oracle's notoriously bad date, time, and calendar classes bundled with Java 7 and earlier.
// http://www.joda.org/joda-time/
// Joda-Time will become outmoded by the JSR 310 Date and Time API introduced in Java 8.
// JSR 310 was inspired by Joda-Time but is not directly based on it.
// http://jcp.org/en/jsr/detail?id=310
// By default, Joda-Time produces strings in the standard ISO 8601 format.
// https://en.wikipedia.org/wiki/ISO_8601
you can create a generic method which takes
- Date (String) (current date or from date),
- Format (String) (your desired fromat) and
- Days (number of days before(-ve value) or after(+ve value))
as input and return your desired date in required format.
following method can resolve this problem.
public String getRequiredDate(String date , String format ,int days){
try{
final Calendar cal = Calendar.getInstance();
cal.setTime(new SimpleDateFormat(format).parse(date));
cal.add(Calendar.DATE, days);
SimpleDateFormat sdf = new SimpleDateFormat(format);
date = sdf.format(cal.getTime());
}
catch(Exception ex){
logger.error(ex.getMessage(), ex);
}
return date;
}
}
In Java 8 we can use directly for this purpose
LocalDate todayDate = LocalDate.now();
By default it provide the format of 2021-06-07, with the help of formater we can change this also
LocalDate previousDate = todayDate.minusDays(5);
Calendar cal2 = Calendar.getInstance();
cal2.add(Calendar.YEAR, -1);
Date dt2 = new Date(cal2.getTimeInMillis());
System.out.println(dt2);

Categories