I was tasked with creating an appointment planner in Java. I have everything done except I am having trouble with making the dates of new appointments be sorted by date.
I have tried switching the order around but no matter what I cannot get new appointments to be sorted properly by date.
{"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
int ind1 = 0,ind2 = 0;
for(int i=0;i<12;i++) {
if(monthArray[i].equalsIgnoreCase(month)) {
ind1=i;
}
if(monthArray[i].equalsIgnoreCase(app.getMonth())) {
ind2=i;
}
}
if(ind1<ind2) {
return 1;
}
else if(ind1==ind2) {
if(this.day<app.getDay()) {
return 1;
}
else if(this.getDay()>app.getDay()) {
return -1;
}
else {
if(this.getHour()<app.getHour()) {
return 1;
}
else if(this.getHour()>app.getHour()) {
return -1;
}
else {
if(this.getMin()<app.getMin()) {
return 1;
}
else if(this.getMin()>app.getMin()) {
return -1;
}
else {
return 0;
}
}
}
}
else {
return -1;
}
}
}
I expect new appointments to be sorted by date but they are not.
Time Zone
A proper appointment system must account for the fact that politicians around the world have shown a proclivity for redefining the time zone(s) under their juridiction. They do so surprisingly often, and with little or no warning.
So your Appointment class should carry two member fields:
LocalDateTime to hold the date and the time of day. Note that this does not represent a moment, is not a point on the timeline. If it holds a value of 3 PM on January 23rd next year, we don’t know if that means 3 PM in Tokyo, Kolkata, Paris, or Montreal — all different moments, several hours apart.
ZoneId for the time zone in which we intend that 3 PM appointment.
Example:
LocalDate ld = LocalDate.of( 2020 , Month.JANUARY , 23 ) ;
LocalTime lt = LocalTime.of( 15 , 0 ) ;
this.localDateTime = LocalDateTime.of( ld , lt ) ;
this.zoneId = ZoneId.of( "America/Los_Angeles" ) ;
Sorting
For sorting purposes, your class can implement the Comparable interface, with the required compareTo method.
The trick is that you want the 3 PM appointments on the east coast of the US, for example, to sort above the 3 PM appointments of the west coast which occur a few hours later.
So the compareTo method must dynamically calculate a moment, determine a specific point on the timeline. Then, compare the moments of the various Appointment objects to sort properly.
First step is being sure that your JVM has been updated with the latest rules about the time zones. Remember, as mentioned above, these change quite often. Updates to Java will often include an update to the “tzdata” zone information. If a time zone you care about has changed more recently, you may need to update the tzdata yourself.
Next step is dynamically applying the zone to the date-time to determine a moment. Apply the ZoneId to the LocalDateTime to get a ZonedDateTime.
ZonedDateTime zdt = this.localDateTime.atZone( this.zoneId ) ;
Adjust that to UTC. Extract a Instant object, always in UTC by definition.
Instant thisInstant = zdt.toInstant() ;
Compare the Instant of this Appointment object with the other one passed to your compareTo. We can, in turn, call the Instant::compareTo method to do the work of actually comparing.
return thisInstant.compareTo( other.localDateTime.atZone( other.zoneId ).toInstant() ) ;
Alternatively, you might choose to use Objects.compare.
Java has a DateTime library that could be very helpful, but I'm assuming you don't want that seeing as you're doing it manually.
https://dzone.com/articles/java-comparable-interface-in-five-minutes
I'd recommend reading something like that, which gives a little bit of information about comparables. This allows you to create a method doing what you're doing, comparing two objects to each other. Then you can use a lot of standard solutions such as Collections.sort in order to test out and use your code more easily.
I'm not sure if that's what you're already doing so i thought I'd throw it out there.
But for the actual problem, the best solution is funnily enough using an inbuilt function.
Integer.compareTo(int a, int b) will compare two integers for you. All you're doing is repeatedly comparing integers. You can run your code like
int comp = Integer.compare(monthA, monthB;
if(comp != 0) return comp;
//proceed with rest of comparisons the same way you did the months
If you are getting appointment date then why dont you directing comparing them instead of comparing month ,date and time.
Though you can simply convert your appointment date to valid date object as below.
String sDate1="31/12/1998";
Date date1=new SimpleDateFormat("dd/MM/yyyy").parse(sDate1);
System.out.println(sDate1+"\t"+date1);
Reference link : https://www.javatpoint.com/java-string-to-date
Then simply compare date object
if (date1.compareTo(date2) > 0) {
some opertaion...
}
Reference link : https://www.mkyong.com/java/how-to-compare-dates-in-java/
Hope this will help you.
I have a date and a number and want to check if this date and this number occurs in a list of other dates within:
+-20 date intervall with the same number
so for example 1, 1.1.2013 and 1,3.1.2013 should reuturn false.
I tried to implement the method something like that:
private List<EventDate> dayIntervall(List<EventDate> eventList) throws Exception {
List<EventDate> resultList = new ArrayList<EventDate>();
for (int i = 0; i < eventList.size(); i++) {
String string = eventList.get(i).getDate();
Date equalDate = new SimpleDateFormat("dd.MM.yyyy", Locale.GERMAN).parse(string);
for (int j = 0; j < eventList.size(); j++) {
String string1 = eventList.get(i).getDate();
Date otherDate = new SimpleDateFormat("dd.MM.yyyy", Locale.GERMAN).parse(string1);
if (check number of i with number of j && check Date) {
//do magic
}
}
}
return resultList;
}
The construction of the iteration method is not that hard. What is hard for me is the date intervall checking part. I tried it like that:
boolean isWithinRange(Date testDate, Date days) {
return !(testDate.before(days) || testDate.after(days));
}
However that does not work because days are not takes as days. Any suggestions on how to fix that?
I really appreciate your answer!
You question is difficult to follow. But given its title, perhaps this will help…
Span Of Time In Joda-Time
The Joda-Time library provides a trio of classes to represent a span of time: Interval, Period, and Duration.
Interval
An Interval object has specific endpoints that lie on the timeline of the Universe. A handy contains method tells if a DateTime object occurs within those endpoints. The beginning endpoint in inclusive while the last endpoint is exclusive.
Time Zones
Note that time zones are important, for handling Daylight Saving Time and other anomalies, and for handling start-of-day. Keep in mind that while a java.util.Date seems like it has a time zone but does not, a DateTime truly does know its own time zone.
Sample Code
Some code off the top of my head (untested)…
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Berlin" );
DateTime dateTime = new DateTime( yourDateGoesHere, timeZone );
Interval interval = new Interval( dateTime.minusDays( 20 ), dateTime.plusDays( 20 ) );
boolean didEventOccurDuringInterval = interval.contains( someOtherDateTime );
Whole Days
If you want whole days, call the withTimeAtStartOfDay method to get first moment of the day. In this case, you probably need to add 21 rather than 20 days for the ending point. As I said above, the end point is exclusive. So if you want whole days, you need the first moment after the time period you care about. You need the moment after the stroke of midnight. If this does not make sense, see my answers to other questions here and here.
Note that Joda-Time includes some "midnight"-related methods and classes. Those are no longer recommended by the Joda team. The "withTimeAtStartOfDay" method takes their place.
DateTime start = dateTime.minusDays( 20 ).withTimeAtStartOfDay();
DateTime stop = dateTime.plusDays( 21 ).withTimeAtStartOfDay(); // 21, not 20, for whole days.
Interval interval = new Interval( start, stop );
You should avoid java.util.Date if at all possible. Using the backport of ThreeTen (the long awaited replacement date/time API coming in JDK8), you can get the number of days between two dates like so:
int daysBetween(LocalDate start, LocalDate end) {
return Math.abs(start.periodUntil(end).getDays());
}
Does that help?
You can get the number of dates in between the 2 dates and compare with your days parameter. Using Joda-Time API it is relatively an easy task: How do I calculate the difference between two dates?.
Code:
SimpleDateFormat format = new SimpleDateFormat("dd.MM.yyyy", Locale.GERMAN);
Date startDate = format.parse("1.1.2013");
Date endDate = format.parse("3.1.2013");
Days d = Days.daysBetween(new DateTime(startDate), new DateTime(endDate));
System.out.println(d.getDays());
Gives,
2
This is possible using Calendar class as well:
Calendar cal = Calendar.getInstance();
cal.setTime(startDate);
System.out.println(cal.fieldDifference(endDate, Calendar.DAY_OF_YEAR));
Gives,
2
This 2 can now be compared to your actual value (20).
This question already has answers here:
How can I determine if a date is between two dates in Java? [duplicate]
(11 answers)
Closed 9 years ago.
I'm trying to write a schedule program in Java and I need to figure out what time it is, and whether the current time is in between two set times. Figuring out the current time is pretty simple, but do you have any suggestions for figuring out whether it is between two times of day. For example, it is 9:33 AM on a Thursday. So I would need to figure out which scheduled section of the week that time corresponds to. How would I go about comparing the time to set periods during the week, for example an Array of sectioned times during a week such as {Monday from 9-10 AM, Tuesday from 3-4 PM, Thursday from 8-11 AM}, and seeing which section of time the current time falls between?
An efficient way to find which period any date lies within would be to have a class;
public class TimePeriod implements Comparable<TimePeriod>{
Date start;
Date end;
//Constructor, getters, setters
boolean isIn(Date date) {
return date.after(start) && date.before(end);
}
public int compareTo(TimePeriod other) {
return start.compareTo(other.start);
}
}
..and then create a sorted list of TimePeriod where you can perform a binary search.
edit:
This might make the binary search easier;
int check(Date date) {
if (isIn(date)) {
return 0;
} else if (start.after(date)) {
return -1;
} else if (end.before(date)) {
return 1;
} else {
throw new IllegalStateException("Time has gone badly wrong");
}
}
If you're using Date Class, you could do it like this
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy hh:mm");
Date before = sdf.parse("07/05/2012 08:00");
Date after = sdf.parse("07/05/2012 08:30");
Date toCheck = sdf.parse("07/05/2012 08:15");
//is toCheck between the two?
boolean isAvailable = (before.getTime() < toCheck.getTime()) && after.getTime() > toCheck.getTime();
EDITED
As suggested by Jonathan Drapeau you could also use compareTo.
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy hh:mm");
Date before = sdf.parse("07/05/2012 08:00");
Date after = sdf.parse("07/05/2012 08:30");
Date toCheck = sdf.parse("07/05/2012 08:15");
//is toCheck between the two?
if you want to include the "initial" and "final" date range
boolean isAvailable = before.compareTo(toCheck) >= 0 && after.compareTo(toCheck) <= 0
if you want to exclude the "initial" and "final" date range
boolean isAvailable = before.compareTo(toCheck) > 0 && after.compareTo(toCheck) < 0
You could use it too on Calendar class.
Anyway, i highly recommend you to use Calendar. It's a way precise class
you could check it like this:
Calendar cal1 = Calendar.getInstance(); // for example 12:00:00
Calendar cal2 = Calendar.getInstance(); // for exmaple 12:30:00
Calendar userTime = Calendar.getInstance(); // time to test: 12:15:00
if(user.after(cal1)&& user.before(cal2)){
//...
}
And to initialize and set times to Calendar, check this:
http://www.tutorialspoint.com/java/util/calendar_settime.htm
I would suggest using the Epoch time.
For a definition of Epoch time: http://en.wikipedia.org/wiki/Epoch_time
Basically, its a number of seconds after a specific date, i believe in 1989. If you translate the 3 times (the current time and the 2 times to compare to) in epoch time you can just use > < = etc.
For information on getting epoch time, Try here (has many languages): http://shafiqissani.wordpress.com/2010/09/30/how-to-get-the-current-epoch-time-unix-timestamp/
Unfortunately, my java is lacking or I'd give you some code :)
Edit:
Java epoch time code:
long epoch = System.currentTimeMillis()/1000;
Because my Java is bad and I don't have an interpreter where I am, I can only suggest using this site to help convert the other dates to epoch time: http://www.epochconverter.com/
There is before(Date) and after(Date) method in Date Class.
secondDate.before(firstDate)
If you use Calendar class, it has explicit before() and after() methods:
Calendar startDate = ...
Calendar endData = ...
isBetween = currentDate.after(startDate) && currentDate.before(endDate);
I want to compare two dates, however I'm running into trouble. 1 date is created from a java.util.date object and the other is manually crafted. The following code is an example:
Date ds = new Date();
DateTime d = new DateTime(ds);
DateTime e = new DateTime(2012,12,07, 0, 0);
System.out.println(d.isEqual(e));
However the test turns out false. I am guessing that it is because of the time. How can I check if these two dates are equal to each other (I mean the Year, month, date are identical)?
System.out.println(d.toDateMidnight().isEqual(e.toDateMidnight()));
or
System.out.println(d.withTimeAtStartOfDay().isEqual(e.withTimeAtStartOfDay()));
You should use toLocalDate():
date1.toLocalDate().isEqual(date2.toLocalDate())
This will get rid of the Time part of the DateTime.
There is another approach, but it does not account for the case where the two dates have a different timezone, so it's less reliable:
date1.withTimeAtStartOfDay().isEqual(date2.withTimeAtStartOfDay())
return DateTimeComparator.getDateOnlyInstance().compare(first, second);
Via How to compare two Dates without the time portion?
If you want to ignore time components (i.e. you want to compare only dates) you can use DateMidnight class instead of Date Time. So your example will look something like this:
Date ds = new Date();
DateMidnight d = new DateMidnight(ds);
DateMidnight e = new DateMidnight(2012, 12, 7);
System.out.println(d.isEqual(e));
But beware, it will print "true" only today :)
Also note that by default JDK Date and all Joda-Time instant classes (DateTime and DateMidnight included) are constructed using default timezone. So if you create one date to compare in code, but retrieve another one from the DB which probably stores dates in UTC you may encounter inconsistencies assuming you are not in UTC time zone.
As they're DateTime objects, their time parts are also taken into consideration when you're comparing them. Try setting the time parts of the first date to 0, like:
d = d.withTime(0, 0, 0, 0);
I stumbled into this question while looking for a comparison with today. Here's how you can compare a date to today :
date1.toLocalDate().isBeforeNow() // works also with isAfterNow
This is a static method which works for me.
public static boolean isSameDay(DateTime date1, DateTime date2){
return date1.withTimeAtStartOfDay().isEqual(date2.withTimeAtStartOfDay());
}
DateTimeComparator.getDateOnlyInstance().compare(obj1, obj2);
obj1 and obj2 can be a String, Long, Date(java.util)... For the details see
http://www.joda.org/joda-time/apidocs/index.html?org/joda/time/DateTimeComparator.html
Write your own method
public boolean checkEqual(DateTime first,DateTime second){
if(first.<getterforyear> == second.<getterforyear> && first.<getterformonth> == second.<getterformonth> && first.<getterforday> == second.<getterforday>){
return true;
}
return false;
}
I would like to have a compareTo method that ignores the time portion of a java.util.Date. I guess there are a number of ways to solve this. What's the simplest way?
Update: while Joda Time was a fine recommendation at the time, use the java.time library from Java 8+ instead where possible.
My preference is to use Joda Time which makes this incredibly easy:
DateTime first = ...;
DateTime second = ...;
LocalDate firstDate = first.toLocalDate();
LocalDate secondDate = second.toLocalDate();
return firstDate.compareTo(secondDate);
EDIT: As noted in comments, if you use DateTimeComparator.getDateOnlyInstance() it's even simpler :)
// TODO: consider extracting the comparator to a field.
return DateTimeComparator.getDateOnlyInstance().compare(first, second);
("Use Joda Time" is the basis of almost all SO questions which ask about java.util.Date or java.util.Calendar. It's a thoroughly superior API. If you're doing anything significant with dates/times, you should really use it if you possibly can.)
If you're absolutely forced to use the built in API, you should create an instance of Calendar with the appropriate date and using the appropriate time zone. You could then set each field in each calendar out of hour, minute, second and millisecond to 0, and compare the resulting times. Definitely icky compared with the Joda solution though :)
The time zone part is important: java.util.Date is always based on UTC. In most cases where I've been interested in a date, that's been a date in a specific time zone. That on its own will force you to use Calendar or Joda Time (unless you want to account for the time zone yourself, which I don't recommend.)
Quick reference for android developers
//Add joda library dependency to your build.gradle file
dependencies {
...
implementation 'joda-time:joda-time:2.9.9'
}
Sample code (example)
DateTimeComparator dateTimeComparator = DateTimeComparator.getDateOnlyInstance();
Date myDateOne = ...;
Date myDateTwo = ...;
int retVal = dateTimeComparator.compare(myDateOne, myDateTwo);
if(retVal == 0)
//both dates are equal
else if(retVal < 0)
//myDateOne is before myDateTwo
else if(retVal > 0)
//myDateOne is after myDateTwo
Apache commons-lang is almost ubiquitous. So what about this?
if (DateUtils.isSameDay(date1, date2)) {
// it's same
} else if (date1.before(date2)) {
// it's before
} else {
// it's after
}
If you really want to use the java.util.Date, you would do something like this:
public class TimeIgnoringComparator implements Comparator<Date> {
public int compare(Date d1, Date d2) {
if (d1.getYear() != d2.getYear())
return d1.getYear() - d2.getYear();
if (d1.getMonth() != d2.getMonth())
return d1.getMonth() - d2.getMonth();
return d1.getDate() - d2.getDate();
}
}
or, using a Calendar instead (preferred, since getYear() and such are deprecated)
public class TimeIgnoringComparator implements Comparator<Calendar> {
public int compare(Calendar c1, Calendar c2) {
if (c1.get(Calendar.YEAR) != c2.get(Calendar.YEAR))
return c1.get(Calendar.YEAR) - c2.get(Calendar.YEAR);
if (c1.get(Calendar.MONTH) != c2.get(Calendar.MONTH))
return c1.get(Calendar.MONTH) - c2.get(Calendar.MONTH);
return c1.get(Calendar.DAY_OF_MONTH) - c2.get(Calendar.DAY_OF_MONTH);
}
}
My preference would be to use the Joda library insetad of java.util.Date directly, as Joda makes a distinction between date and time (see YearMonthDay and DateTime classes).
However, if you do wish to use java.util.Date I would suggest writing a utility method; e.g.
public static Date setTimeToMidnight(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime( date );
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTime();
}
Any opinions on this alternative?
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
sdf.format(date1).equals(sdf.format(date2));
If you want to compare only the month, day and year of two dates, following code works for me:
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
sdf.format(date1).equals(sdf.format(date2));
Thanks Rob.
tl;dr
myJavaUtilDate1.toInstant()
.atZone( ZoneId.of( "America/Montreal" ) )
.toLocalDate()
.isEqual (
myJavaUtilDate2.toInstant()
.atZone( ZoneId.of( "America/Montreal" ) )
.toLocalDate()
)
Avoid legacy date-time classes
Avoid the troublesome old legacy date-time classes such as Date & Calendar, now supplanted by the java.time classes.
Using java.time
A java.util.Date represents a moment on the timeline in UTC. The equivalent in java.time is Instant. You may convert using new methods added to the legacy class.
Instant instant1 = myJavaUtilDate1.toInstant();
Instant instant2 = myJavaUtilDate2.toInstant();
You want to compare by date. A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" );
Apply the ZoneId to the Instant to get a ZonedDateTime.
ZonedDateTime zdt1 = instant1.atZone( z );
ZonedDateTime zdt2 = instant2.atZone( z );
The LocalDate class represents a date-only value without time-of-day and without time zone. We can extract a LocalDate from a ZonedDateTime, effectively eliminating the time-of-day portion.
LocalDate localDate1 = zdt1.toLocalDate();
LocalDate localDate2 = zdt2.toLocalDate();
Now compare, using methods such as isEqual, isBefore, and isAfter.
Boolean sameDate = localDate1.isEqual( localDate2 );
See this code run live at IdeOne.com.
instant1: 2017-03-25T04:13:10.971Z | instant2: 2017-03-24T22:13:10.972Z
zdt1: 2017-03-25T00:13:10.971-04:00[America/Montreal] | zdt2: 2017-03-24T18:13:10.972-04:00[America/Montreal]
localDate1: 2017-03-25 | localDate2: 2017-03-24
sameDate: false
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.
I too prefer Joda Time, but here's an alternative:
long oneDay = 24 * 60 * 60 * 1000
long d1 = first.getTime() / oneDay
long d2 = second.getTime() / oneDay
d1 == d2
EDIT
I put the UTC thingy below in case you need to compare dates for a specific timezone other than UTC. If you do have such a need, though, then I really advise going for Joda.
long oneDay = 24 * 60 * 60 * 1000
long hoursFromUTC = -4 * 60 * 60 * 1000 // EST with Daylight Time Savings
long d1 = (first.getTime() + hoursFromUTC) / oneDay
long d2 = (second.getTime() + hoursFromUTC) / oneDay
d1 == d2
Already mentioned apache commons-utils:
org.apache.commons.lang.time.DateUtils.truncate(date, Calendar.DAY_OF_MONTH)
gives you Date object containing only date, without time, and you can compare it with Date.compareTo
If you're using Java 8, you should use the java.time.* classes to compare dates - it's preferred to the various java.util.* classes
eg; https://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html
LocalDate date1 = LocalDate.of(2016, 2, 14);
LocalDate date2 = LocalDate.of(2015, 5, 23);
date1.isAfter(date2);
I am afraid there is no method of comparing two dates that could be called "easy" or "simple".
When comparing two time instances with any sort of reduced precision (e.g. just comparing dates), you must always take into account how time zone affects the comparison.
If date1 is specifying an event that occurred in +2 timezone and date2 is specifying an event that occurred in EST, for example, you must take care to properly understand the implications of the comparison.
Is your purpose to figure out if the two events occurred in the same calendar date in their own respective time zones? Or do You need to know if the two dates fall into the same calendar date in a specific time zone (UTC or your local TZ, for example).
Once you figure out what it is actually that You are trying to compare, it is just a matter of getting the year-month-date triple in an appropriate time zone and do the comparison.
Joda time might make the actual comparison operation look much cleaner, but the semantics of the comparison are still something You need to figure out yourself.
Simply Check DAY_OF_YEAR in combination with YEAR property
boolean isSameDay =
firstCal.get(Calendar.YEAR) == secondCal.get(Calendar.YEAR) &&
firstCal.get(Calendar.DAY_OF_YEAR) == secondCal.get(Calendar.DAY_OF_YEAR)
EDIT:
Now we can use the power of Kotlin extension functions
fun Calendar.isSameDay(second: Calendar): Boolean {
return this[Calendar.YEAR] == second[Calendar.YEAR] && this[Calendar.DAY_OF_YEAR] == second[Calendar.DAY_OF_YEAR]
}
fun Calendar.compareDatesOnly(other: Calendar): Int {
return when {
isSameDay(other) -> 0
before(other) -> -1
else -> 1
}
}
If you just want to compare only two dates without time, then following code might help you:
final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
Date dLastUpdateDate = dateFormat.parse(20111116);
Date dCurrentDate = dateFormat.parse(dateFormat.format(new Date()));
if (dCurrentDate.after(dLastUpdateDate))
{
add your logic
}
I don't know it is new think or else, but i show you as i done
SimpleDateFormat dtf = new SimpleDateFormat("dd/MM/yyyy");
Date td_date = new Date();
String first_date = dtf.format(td_date); //First seted in String
String second_date = "30/11/2020"; //Second date you can set hear in String
String result = (first_date.equals(second_date)) ? "Yes, Its Equals":"No, It is not Equals";
System.out.println(result);
Here is a solution from this blog: http://brigitzblog.blogspot.com/2011/10/java-compare-dates.html
long milliseconds1 = calendar1.getTimeInMillis();
long milliseconds2 = calendar2.getTimeInMillis();
long diff = milliseconds2 - milliseconds1;
long diffDays = diff / (24 * 60 * 60 * 1000);
System.out.println("Time in days: " + diffDays + " days.");
i.e. you can see if the time difference in milliseconds is less than the length of one day.
`
SimpleDateFormat sdf= new SimpleDateFormat("MM/dd/yyyy")
Date date1=sdf.parse("03/25/2015");
Date currentDate= sdf.parse(sdf.format(new Date()));
return date1.compareTo(currentDate);
`
Using http://mvnrepository.com/artifact/commons-lang/commons-lang
Date date1 = new Date();
Date date2 = new Date();
if (DateUtils.truncatedCompareTo(date1, date2, Calendar.DAY_OF_MONTH) == 0)
// TRUE
else
// FALSE
In Java 8 you can use LocalDate which is very similar to the one from Joda Time.
public Date saveDateWithoutTime(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime( date );
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.HOUR, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
return calendar.getTime();
}
This will help you to compare dates without considering the time.
Using the getDateInstance of SimpleDateFormat, we can compare only two date object without time. Execute the below code.
public static void main(String[] args) {
Date date1 = new Date();
Date date2 = new Date();
DateFormat dfg = SimpleDateFormat.getDateInstance(DateFormat.DATE_FIELD);
String dateDtr1 = dfg.format(date1);
String dateDtr2 = dfg.format(date2);
System.out.println(dateDtr1+" : "+dateDtr2);
System.out.println(dateDtr1.equals(dateDtr2));
}
Another Simple compare method based on the answers here and my mentor guidance
public static int compare(Date d1, Date d2) {
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
c1.setTime(d1);
c1.set(Calendar.MILLISECOND, 0);
c1.set(Calendar.SECOND, 0);
c1.set(Calendar.MINUTE, 0);
c1.set(Calendar.HOUR_OF_DAY, 0);
c2.setTime(d2);
c2.set(Calendar.MILLISECOND, 0);
c2.set(Calendar.SECOND, 0);
c2.set(Calendar.MINUTE, 0);
c2.set(Calendar.HOUR_OF_DAY, 0);
return c1.getTime().compareTo(c2.getTime());
}
EDIT:
According to #Jonathan Drapeau, the code above fail some cases (I would like to see those cases, please) and he suggested the following as I understand:
public static int compare2(Date d1, Date d2) {
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
c1.clear();
c2.clear();
c1.set(Calendar.YEAR, d1.getYear());
c1.set(Calendar.MONTH, d1.getMonth());
c1.set(Calendar.DAY_OF_MONTH, d1.getDay());
c2.set(Calendar.YEAR, d2.getYear());
c2.set(Calendar.MONTH, d2.getMonth());
c2.set(Calendar.DAY_OF_MONTH, d2.getDay());
return c1.getTime().compareTo(c2.getTime());
}
Please notice that, the Date class is deprecated cause it was not amenable to internationalization. The Calendar class is used instead!
First, be aware that this operation depends on the time zone. So choose whether you want to do it in UTC, in the computer’s time zone, in your own favourite time zone or where. If you are not yet convinced it matters, see my example at the bottom of this answer.
Since your question isn’t quite clear about this, I am assuming that you have a class with an instance field representing a point in time and implementing Comparable, and you want the natural ordering of your objects to be by the date, but not the time, of that field. For example:
public class ArnesClass implements Comparable<ArnesClass> {
private static final ZoneId arnesTimeZone = ZoneId.systemDefault();
private Instant when;
#Override
public int compareTo(ArnesClass o) {
// question is what to put here
}
}
Java 8 java.time classes
I have taken the freedom of changing the type of your instance field from Date to Instant, the corresponding class in Java 8. I promise to return to the treatment of Date below. I have also added a time zone constant. You may set it to ZoneOffset.UTC or ZoneId.of("Europe/Stockholm") or what you find appropriate (setting it to a ZoneOffset works because ZoneOffset is a subclass of ZoneId).
I have chosen to show the solution using the Java 8 classes. You asked for the simplest way, right? :-) Here’s the compareTo method you asked for:
public int compareTo(ArnesClass o) {
LocalDate dateWithoutTime = when.atZone(arnesTimeZone).toLocalDate();
LocalDate otherDateWithoutTime = o.when.atZone(arnesTimeZone).toLocalDate();
return dateWithoutTime.compareTo(otherDateWithoutTime);
}
If you never need the time part of when, it is of course easier to declare when a LocalDate and skip all conversions. Then we don’t have to worry about the time zone anymore either.
Now suppose that for some reason you cannot declare your when field an Instant or you want to keep it an old-fashioned Date. If you can still use Java 8, just convert it to Instant, then do as before:
LocalDate dateWithoutTime = when.toInstant().atZone(arnesTimeZone).toLocalDate();
Similarly for o.when.
No Java 8?
If you cannot use java 8, there are two options:
Solve it using one of the old classes, either Calendar or SimpleDateFormat.
Use the backport of the Java 8 date and time classes to Java 6 and 7, then just do as above. I include a link at the bottom. Do not use JodaTime. JodaTime was probably a good suggestion when the answers recommending it were written; but JodaTime is now in maintenance mode, so the ThreeTen backport is a better and more futureproof option.
The old-fashioned ways
Adamski’s answer shows you how to strip the time part off a Date using the Calendar class. I suggest you use getInstance(TimeZone) to obtain the Calendar instance for the time zone you want. As an alternative you may use the idea from the second half of Jorn’s answer.
Using SimpleDateFormat is really an indirect way of using Calendar since a SimpleDateFormat contains a Calendar object. However, you may find it less troublesome than using Calendar directly:
private static final TimeZone arnesTimeZone = TimeZone.getTimeZone("Europe/Stockholm");
private static final DateFormat formatter = new SimpleDateFormat("yyyyMMdd");
static {
formatter.setTimeZone(arnesTimeZone);
}
private Date when;
#Override
public int compareTo(ArnesClass o) {
return formatter.format(when).compareTo(formatter.format(o.when));
}
This was inspired by Rob’s answer.
Time zone dependency
Why do we have to pick a specific time zone? Say that we want to compare two times that in UTC are March 24 0:00 (midnight) and 12:00 (noon). If you do that in CET (say, Europe/Paris), they are 1 am and 1 pm on March 24, that is, the same date. In New York (Eastern Daylight Time), they are 20:00 on March 23 and 8:00 on March 24, that is, not the same date. So it makes a difference which time zone you pick. If you just rely on the computer’s default, you may be in for surprises when someone tries to run your code on a computer in another place in this globalized world.
Link
Link to ThreeTen Backport, the backport of the Java 8 date and time classes to Java 6 and 7: http://www.threeten.org/threetenbp/.
My proposition:
Calendar cal = Calendar.getInstance();
cal.set(1999,10,01); // nov 1st, 1999
cal.set(Calendar.AM_PM,Calendar.AM);
cal.set(Calendar.HOUR,0);
cal.set(Calendar.MINUTE,0);
cal.set(Calendar.SECOND,0);
cal.set(Calendar.MILLISECOND,0);
// date column in the Thought table is of type sql date
Thought thought = thoughtDao.getThought(date, language);
Assert.assertEquals(cal.getTime(), thought.getDate());
Using Apache commons you can do:
import org.apache.commons.lang3.time.DateUtils
DateUtils.truncatedEquals(first, second, Calendar.DAY_OF_MONTH)
public static Date getZeroTimeDate(Date fecha) {
Date res = fecha;
Calendar calendar = Calendar.getInstance();
calendar.setTime( fecha );
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
res = calendar.getTime();
return res;
}
Date currentDate = getZeroTimeDate(new Date());// get current date
this is the simplest way to solve this problem.
I solved this by comparing by timestamp:
Calendar last = Calendar.getInstance();
last.setTimeInMillis(firstTimeInMillis);
Calendar current = Calendar.getInstance();
if (last.get(Calendar.DAY_OF_MONTH) != current.get(Calendar.DAY_OF_MONTH)) {
//not the same day
}
I avoid to use Joda Time because on Android uses a huge space. Size matters. ;)
Another solution using Java 8 and Instant, is using the truncatedTo method
Returns a copy of this Instant truncated to the specified unit.
Example:
#Test
public void dateTruncate() throws InterruptedException {
Instant now = Instant.now();
Thread.sleep(1000*5);
Instant later = Instant.now();
assertThat(now, not(equalTo(later)));
assertThat(now.truncatedTo(ChronoUnit.DAYS), equalTo(later.truncatedTo(ChronoUnit.DAYS)));
}
// Create one day 00:00:00 calendar
int oneDayTimeStamp = 1523017440;
Calendar oneDayCal = Calendar.getInstance();
oneDayCal.setTimeInMillis(oneDayTimeStamp * 1000L);
oneDayCal.set(Calendar.HOUR_OF_DAY, 0);
oneDayCal.set(Calendar.MINUTE, 0);
oneDayCal.set(Calendar.SECOND, 0);
oneDayCal.set(Calendar.MILLISECOND, 0);
// Create current day 00:00:00 calendar
Calendar currentCal = Calendar.getInstance();
currentCal.set(Calendar.HOUR_OF_DAY, 0);
currentCal.set(Calendar.MINUTE, 0);
currentCal.set(Calendar.SECOND, 0);
currentCal.set(Calendar.MILLISECOND, 0);
if (oneDayCal.compareTo(currentCal) == 0) {
// Same day (excluding time)
}
If you strictly want to use Date ( java.util.Date ), or without any use of external Library. Use this :
public Boolean compareDateWithoutTime(Date d1, Date d2) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
return sdf.format(d1).equals(sdf.format(d2));
}
Date today = new Date();
Date endDate = new Date();//this
endDate.setTime(endDate.getTime() - ((endDate.getHours()*60*60*1000) + (endDate.getMinutes()*60*1000) + (endDate.getSeconds()*1000)));
today.setTime(today.getTime() - ((today.getHours()*60*60*1000) + (today.getMinutes()*60*1000) + (today.getSeconds()*1000)));
System.out.println(endDate.compareTo(today) <= 0);
I am simply setting hours/minutes/second to 0 so no issue with the time as time will be same now for both dates. now you simply use compareTo. This method helped to find "if dueDate is today" where true means Yes.