Java Calendar problem: why are these two Dates not equal? - java

import java.io.*;
public class testing {
public static void main(String a[]) throws Exception{
Date d1=new Date();
Thread.sleep(2000);
Date d2=new Date();
if(d1.equals(d2)){
System.out.println("Both equal");
}else{
System.out.println("Both not equal");
}
Calendar c1=Calendar.getInstance();
Calendar c2=Calendar.getInstance();
c1.setTime(d1);
c2.setTime(d2);
c1.clear(Calendar.HOUR);
c1.clear(Calendar.MINUTE);
c1.clear(Calendar.SECOND);
c2.clear(Calendar.HOUR);
c2.clear(Calendar.MINUTE);
c2.clear(Calendar.SECOND);
if(c2.compareTo(c1) == 0){
System.out.println("Cal Equal");
}else {
System.out.println("Cal Not Equal");
}
}
}
When I run the above code multiple times of which each time (for printing if conditions of date) 'Both not equal' is printed but (for if condition of Calendar) sometimes it prints 'Cal Equal' and sometimes 'Cal Not Equal'. Can anyone please explain me why this is so?
The main reason I was trying this because I want to compare two dates. Both have same day, month and Year but different time of the day when the objects were created. I want them to be compared equal(same). How should I do this?

Truncate the Milliseconds field
Calendars have milliseconds, too. Add this:
c1.clear(Calendar.MILLISECOND);
c2.clear(Calendar.MILLISECOND);
But it's easier to achieve that functionality using DateUtils.truncate() from Apache Commons / Lang
c1 = DateUtils.truncate(c1, Calendar.DATE);
c2 = DateUtils.truncate(c2, Calendar.DATE);
This removes all hours, minutes, seconds and milliseconds.

I believe Calendar also has Millisecond precision. If you want to continue your code, add
c1.clear(Calendar.MILLISECOND);
c2.clear(Calendar.MILLISECOND);
then try your comparison.

use JodaTime instead, its so much better (than the standard Date and Calendar) for manipulating dates and time.

You need to clear milleseconds

After
Calendar c1=Calendar.getInstance();
add
c1.clear();
That's a bit easier to type than c1.clear(Calendar.MILLISECOND);
Works a treat.

Reset time using the below method before compare dates
private Calendar resetHours(Calendar cal) {
cal.set(Calendar.HOUR, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND,0);
cal.set(Calendar.HOUR_OF_DAY,0);
cal.set(Calendar.MILLISECOND,0);
return cal;
}

Related

Round by next quarter minutes always

We have a requirement to Round by next quarter minutes in Java code, for example:
if current date time is 2020-05-28T10:01:00
then, round up to next quarter to make it 2020-05-28T10:15:00
if current date time is 2020-05-28T10:15:01
then, round up to next quarter to make it 2020-05-28T10:30:00
if current date time is 2020-05-28T10:46:15
then, round up to next quarter to make it 2020-05-28T11:00:00
if current date time is 2020-12-31T23:47:00
then, round up to next quarter to make it 2021-01-01T00:00:00
Can someone please provide Java code to achieve this. Any help is appreciated.
Tried below code but unable to get the output which I'm looking for:
import java.util.Calendar;
import java.util.Date;
public class Main {
public static void main(String[] args) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
int round = calendar.get(Calendar.MINUTE) % 15;
calendar.add(Calendar.MINUTE, round < 8 ? -round : (15-round));
calendar.set( Calendar.SECOND, 0 );
System.out.println(calendar.getTime());
}
}
This can be easily done using the LocalDateTime class from the java.time package, which you should be using anyway1.
public static LocalDateTime roundUpToQuarter(LocalDateTime datetime) {
int minutesToAdd = 15 - (datetime.getMinute() % 15);
return datetime
.plusMinutes(minutesToAdd)
.truncatedTo(ChronoUnit.MINUTES);
}
This calculation involving the modulus operator makes sure that we get the number of minutes to add to go to the next full quarter. The truncatedTo(ChronoUnit.MINUTES) call makes in turn sure that all fields smaller than 'minutes' are set to zero.
Update: I'm not certain of your exact use case, but, as Basil pointed out, if you want to represent a moment on the timeline, then you also need a timezone or offset. This can be done by replacing LocalDateTime instances with ZonedDateTime in the abovementioned method.
1 The Date, Calendar and SimpleDateFormat classes are obsolete. They may work in simple cases, but they will cause trouble in more complex cases. See What's wrong with Java Date & Time API?.
You can try below code.
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date(1609438620000l));
int fraction = calendar.get(Calendar.MINUTE) / 15;
switch (fraction) {
case 0: {
calendar.set(Calendar.MINUTE, 0);
break;
}
case 1: {
calendar.set(Calendar.MINUTE, 15);
break;
}
case 2: {
calendar.set(Calendar.MINUTE, 30);
break;
}
default: {
calendar.set(Calendar.MINUTE, 45);
break;
}
}
calendar.add(Calendar.MINUTE, 15);
calendar.set(Calendar.SECOND, 0);
System.out.println(calendar.getTime());

Subtract days from Current Date using Calendar Object

I am trying to subtract days from the current date using the java.util.Calendar object. My problem here is the days to subtract can be positive or negative. My code is as follows
public class Test {
public static void main(String[] args) {
int pastValidationDays=2;
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_MONTH, - pastValidationDays);
}
}
As per the above code if the date is 20/1/2015 it will give me 18/1/2015
Now say if the pastValidationDays= -2(negative value) then also it should subtract from the current date. As per the above code if i say
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_MONTH, - pastValidationDays);
then it is adding up the days instead of subtracting. Say if the current date 20/1/2015 it is giving me 22/1/2015. But in this case as well i need the date as 18/1/2015.
One of the way i am doing is as below
if (pastValidationDays < 0){
calendar.add(Calendar.DAY_OF_MONTH, pastValidationDays);
}else{
calendar.add(Calendar.DAY_OF_MONTH, -pastValidationDays);
}
Is this a good approach or can it be done this way
calendar.add(Calendar.DAY_OF_MONTH, - Math.abs(pastValidationDays));
I want to subtract the days using calendar object only. I do not want to use JODA time and other objects. Please suggest other approaches if any. Thanks in advance

Java date and age

I am using a JXDatepicker to get the birth date of a person, and what i have to do is set another JXDatepicker with the retirement date. So the idea here is to get the year of the birth date and to increment it with one year in a loop until the "person" reaches 60 years old and keep the same day and month of birth.. Or i think that's what i have to do. but i can't seem to find how to use the Calendar classes nor the DateFormat classes to do this calculation, i tried different things but nothing works, the closest i got is the date 01/01/1970, which can't be the person's retirement date since the birth date i'm testing is always in 2014 so it should be 2074.
So how can i do the calculation? I'd be grateful if someone could give me an example on how to do it.
(It might seem that i didn't do enough researches, but i did, and i don't find why i would mention what i found since it didn't help me)
You shouldn't write any loop to add 60 years to your date.
You can get a selected date from your JXDatePicker and do it like that:
final Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.YEAR, 60);
final Date retirementDate = cal.getTime();
Why on earth would you have to add 1 in a loop 60 times? Why don't you just add 60?
import java.text.SimpleDateFormat;
import java.util.Calendar;
public class Main {
public static void main(String... args){
SimpleDateFormat df = new SimpleDateFormat("MM/dd/YYYY");
Calendar c = Calendar.getInstance();
System.out.println(df.format(c.getTime())); //prints 05/14/2014
c.add(Calendar.YEAR, 60);
System.out.println(df.format(c.getTime())); //prints 05/14/2074
}
}

How to compare just the day in a java date?

I'm trying to do a simple date comparison between yesterday and today
if (yesterday.before(today)) {
...
}
The issue is that with the before method I will eval to true even if it's just a few seconds difference. How might I compare just the day (because I only want to eval this to true if it was the previous day (minutes/seconds should be ignored)
Thank you in advance
using DateUtils -
if (!DateUtils.isSameDay(yesterday, today) && (yesterday.before(today)) {
//...
}
EDIT: it can be done without DateUtils as well. See this thread.
If you don't want to use a 3rd party library implement a method like this:
public boolean before(Calendar yesterday, Calendar today) {
if(yesterday == today) return false;
if(yesterday == null || today == null) return false;
return yesterday.get(Calendar.YEAR) < today.get(Calendar.YEAR) ? true :
yesterday.get(Calendar.YEAR) == today.get(Calendar.YEAR) && yesterday.get(Calendar.DAY_OF_YEAR) < today.get(Calendar.DAY_OF_YEAR);
}
If you're up to adding a library that handles dates better than the standard Java libraries, you might want to look at Joda.
Using Joda, you can compute difference between days by:
Days d = Days.daysBetween(startDate, endDate);
int days = d.getDays();
where startDate and endDate are the Joda version of dates, DateTime (actually a superclass of that).
Converting Java Date objects to Joda DateTime objects can be done by a constructor call:
DateTime dateTime = new DateTime(javaDate);
Adding this library may be overkill for this specific problem, but if you deal with date and time manipulation a lot, the library is definitely worth it.
If you want to stick to Date you could temporarily lower your current date by one day. If before() still leads to the same result you have a timespan of at least one day.
final static long DAY_MILLIS = 86400000;
Date d1 = new Date(2011, 06, 18);
Date d2 = new Date(2011, 06, 16);
Date temp = new Date(d1.getTime() - DAY_MILLIS);
if (temp.before(d2))
// Do stuff
}
Please note I used a deprecated constructor but it should do the job.

Check a Date is between two dates in Java [duplicate]

This question already has answers here:
How do I check if a date is within a certain range?
(17 answers)
Closed 7 years ago.
One thing I want to know is how to calculate what date will it be 10 days from today.
Second thing is to check if one Date is between two other Dates.
For example, let's say I have an app that shows what events I need to do in the next 10 days (planner). Now how can I see if the date I assigned to an event is between today and the date that is 10 days from today?
Manipulating and comparing dates using java.util.Date and java.util.Calendar is pretty a pain, that's why JodaTime exist. None of the answers as far have covered the time in question. The comparisons may fail when the dates have a non-zero time. It's also unclear whether you want an inclusive or exclusive comparison. Most of the answers posted so far suggest exclusive comparision (i.e. May 24 is not between May 20 and May 24) while in real it would make more sense to make it inclusive (i.e. May 24 is between May 20 and May 24).
One thing I want to know is how to calculate what date will it be 10 days from today.
With the standard Java SE 6 API, you need java.util.Calendar for this.
Calendar plus10days = Calendar.getInstance();
plus10days.add(Calendar.DAY_OF_YEAR, 10);
With JodaTime you would do like this:
DateTime plus10days = new DateTime().plusDays(10);
Second thing is to check if one Date is between two other Dates. For example, let's say I have an app that shows what events I need to do in the next 10 days (planner). Now how can I see if the date I assigned to an event is between today and the date that is 10 days from today?
Now comes the terrible part with Calendar. Let's prepare first:
Calendar now = Calendar.getInstance();
Calendar plus10days = Calendar.getInstance();
plus10days.add(Calendar.DAY_OF_YEAR, 10);
Calendar event = Calendar.getInstance();
event.set(year, month - 1, day); // Or setTime(date);
To compare reliably using Calendar#before() and Calendar#after(), we need to get rid of the time first. Imagine it's currently 24 May 2010 at 9.00 AM and that the event's date is set to 24 May 2010 without time. When you want inclusive comparison, you would like to make it return true at the same day. I.e. both the (event.equals(now) || event.after(now)) or -shorter but equally- (!event.before(now)) should return true. But actually none does that due to the presence of the time in now. You need to clear the time in all calendar instances first like follows:
calendar.clear(Calendar.HOUR);
calendar.clear(Calendar.HOUR_OF_DAY);
calendar.clear(Calendar.MINUTE);
calendar.clear(Calendar.SECOND);
calendar.clear(Calendar.MILLISECOND);
Alternatively you can also compare on day/month/year only.
if (event.get(Calendar.YEAR) >= now.get(Calendar.YEAR)
&& event.get(Calendar.MONTH) >= now.get(Calendar.MONTH)
&& event.get(Calendar.DAY_OF_MONTH) >= now.get(Calendar.DAY_OF_MONTH)
{
// event is equal or after today.
}
Very verbose all.
With JodaTime you can just use DateTime#toLocalDate() to get the date part only:
LocalDate now = new DateTime().toLocalDate();
LocalDate plus10days = now.plusDays(10);
LocalDate event = new DateTime(year, month, day, 0, 0, 0, 0).toLocalDate();
if (!event.isBefore(now) && !event.isAfter(plus10days)) {
// Event is between now and 10 days (inclusive).
}
Yes, the above is really all you need to do.
public static boolean between(Date date, Date dateStart, Date dateEnd) {
if (date != null && dateStart != null && dateEnd != null) {
if (date.after(dateStart) && date.before(dateEnd)) {
return true;
}
else {
return false;
}
}
return false;
}
EDIT: Another suggested variant:
public Boolean checkDate(Date startDate, Date endDate, Date checkDate) {
Interval interval = new Interval(new DateTime(startDate),
new DateTime(endDate));
return interval.contains(new DateTime(checkDate));
}
Use JodaTime calendar replacement classes: http://joda-time.sourceforge.net/
You can use before, after and compareTo methods of Date class.
Here're some examples
http://www.roseindia.net/java/example/java/util/CompareDate.shtml
http://www.javafaq.nu/java-example-code-287.html
http://www.esus.com/javaindex/j2se/jdk1.2/javautil/dates/comparingdates.html
And here's API on Date class
http://java.sun.com/j2se/1.4.2/docs/api/java/util/Date.html
Good Luck!
To add ten days:
Date today = new Date();
Calendar cal = new GregorianCalendar();
cal.setTime(today);
cal.add(Calendar.DAY_OF_YEAR, 10);
To check if between two dates:
myDate.after(firstDate) && myDate.before(lastDate);
To check if date is between two dates, here is simple program:
public static void main(String[] args) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
String oeStartDateStr = "04/01/";
String oeEndDateStr = "11/14/";
Calendar cal = Calendar.getInstance();
Integer year = cal.get(Calendar.YEAR);
oeStartDateStr = oeStartDateStr.concat(year.toString());
oeEndDateStr = oeEndDateStr.concat(year.toString());
Date startDate = sdf.parse(oeStartDateStr);
Date endDate = sdf.parse(oeEndDateStr);
Date d = new Date();
String currDt = sdf.format(d);
if((d.after(startDate) && (d.before(endDate))) || (currDt.equals(sdf.format(startDate)) ||currDt.equals(sdf.format(endDate)))){
System.out.println("Date is between 1st april to 14th nov...");
}
else{
System.out.println("Date is not between 1st april to 14th nov...");
}
}
I took the initial answer and modified it a bit. I consider if the dates are equal to be "inside"..
private static boolean between(Date date, Date dateStart, Date dateEnd) {
if (date != null && dateStart != null && dateEnd != null) {
return (dateEqualOrAfter(date, dateStart) && dateEqualOrBefore(date, dateEnd));
}
return false;
}
private static boolean dateEqualOrAfter(Date dateInQuestion, Date date2)
{
if (dateInQuestion.equals(date2))
return true;
return (dateInQuestion.after(date2));
}
private static boolean dateEqualOrBefore(Date dateInQuestion, Date date2)
{
if (dateInQuestion.equals(date2))
return true;
return (dateInQuestion.before(date2));
}

Categories

Resources