How should I properly compare two dates? - java

Having some trouble implementing this simple task.
Basically I want to compare two dates(some older date vs new date). I want to know if the older date is more than x months old and y days old.
int monthDiff = new Date().getMonth() - detail.getCdLastUpdate().getMonth();
int dayDiff = new Date().getDay() - detail.getCdLastUpdate().getMonth();
System.out.println("\tthe last update date and new date month diff is --> " + monthDiff);
System.out.println("\tthe last update date and new date day diff is --> " + dayDiff);
If older date is 2012-09-21 00:00:00.0, currently, it will return negative numbers. I need to find out if the older date is EXACTLY 6 months and 4 days before new Date(). I'm thinking of using absolute values of both but just can't brain today.
Edit: I know about joda but I cannot use it. I must use Java JDK.
Edit 2: I'll try out the methods listed, if all failed I'll use Joda.

JDK dates have before and after methods, returning boolean, to accomplish your task:
Date now = new Date();
Calendar compareTo = Calendar.getInstance();
compareTo.add(Calendar.MONTH, -6);
compareTo.add(Calendar.DATE, -4);
if (compareTo.getTime().before(now)) {
// after
} else {
// before or equal
}

The best way I can think of is to use Joda-Time library. Example from their site:
Days d = Days.daysBetween(startDate, endDate);
int days = d.getDays();
Or number of months:
Months m = Months.monthsBetween(startDate, endDate)
int months = m.getMonths();
where:
DateTime startDate = new DateTime(/*jdk Date*/);
DateTime endDate = new DateTime(/*jdk Date*/);

Sigh, it is up to me to add the inevitable "use JodaTime" answer.
JodaTime gives you specific data types for all significant time distances.
Date yourReferenceDate = // get date from somewhere
int months = Months.monthsBetween(
new DateTime(yourReferenceDate),
DateTime.now()
).getMonths();

Related

Add decimal month to Date in java

i need to add a decimal amount of month to a java date :
-> i can use this code with joda time api to add a natural amount of months to a date. But how can i add a decimal amount of month ( for example 3.5) to a date ?
Date date = new Date();
DateTime dateTime = new DateTime(date);
dateTime = dateTime.plusMonths(3);
Date newDate = dateTime.toDate();
This will give you an approximation. It’s the best you can get.
long oneMonthInNanos = ChronoUnit.MONTHS.getDuration().toNanos();
ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Asia/Phnom_Penh"));
System.out.println("Now " + now);
System.out.println("In 3.5 months " + now.plusNanos(Math.round(3.5 * oneMonthInNanos)));
System.out.println("In 4.5 months " + now.plusNanos(Math.round(4.5 * oneMonthInNanos)));
System.out.println("In 12 months " + now.plusNanos(Math.round(12.0 * oneMonthInNanos)));
Output when I ran the code just now, was:
Now 2018-11-06T22:31:36.460573+07:00[Asia/Phnom_Penh]
In 3.5 months 2019-02-21T11:13:27.460573+07:00[Asia/Phnom_Penh]
In 4.5 months 2019-03-23T21:42:33.460573+07:00[Asia/Phnom_Penh]
In 12 months 2019-11-07T04:20:48.460573+07:00[Asia/Phnom_Penh]
As has been said in comments, there is no really good definition of a fractional number of months. When you compare the first and the last date-time you also clearly see that 12 months don’t add up to a year precisely, though pretty close. Please check yourself whether the results are good enough for your purpose.
I am using java.time. I din’t know whether something similar is possible in Joda-Time.

Java - get number of days between dates [duplicate]

This question already has answers here:
Calculating days between two dates with Java
(16 answers)
Closed 5 years ago.
I've got a list of dates in format "yyyy-MM-dd", I'd like to have a number of days between my today date "2017-04-15" and first date from list which is higher than mine today date.
I am assuming that your events are not sorted by date. I am assuming that you can use Java 8. This is one of the tasks that have become so much easier with the java.time classes introduced in Java 8 (and backported to Java 6 and 7).
Use LocalDate.now() to get today’s date.
Iterate through your events, all the time keeping track of the closest future event date. For each event use LocalDate.parse() to convert the event’s date to a LocalDate. The 1-arg parse method fits your format. Compare with today’s date and with the earliest future event date encountered so far; if between, store as the new closest date. Use isAfter() and/or isBefore for the comparisons.
After your loop, you will either know the date or you will know that there are no future events at all. In the former case, use ChronoUnit.DAYS.between() to get the number of days from the current date to the event date.
Solution 1
If you are using joda library, then it will be easy, you can use Days.daysBetween :
Date startDate = ...;
Date endDate = ...;
int nbrDays = Days.daysBetween(new LocalDate(startDate), new LocalDate(endDate)).getDays();
Solution 2
Date startDate = ...;
Date endDate = ...;
Calendar cal = Calendar.getInstance();
cal.setTime(startDate);
int day1 = cal.get(Calendar.DAY_OF_MONTH);
cal.setTime(endDate);
int day2 = cal.get(Calendar.DAY_OF_MONTH);
int nbrDays = day1 - day2;
System.out.println(nbrDays);
You have to import :
import java.util.Calendar;
import java.util.Date;
Solution 3
If your dates are in this format "yyyy-MM-dd" so you can have two dates like this :
String date1 = "1991-07-03";
String date2 = "2017-04-15";
What you should to do, split your dates with - :
String spl1[] = date1.split("-");
String spl2[] = date2.split("-");
Calculate the difference between the two dates :
int year1 = Integer.parseInt(spl1[0]);
int month1 = Integer.parseInt(spl1[1]);
int days1 = Integer.parseInt(spl1[2]);
int year2 = Integer.parseInt(spl2[0]);
int month2 = Integer.parseInt(spl2[1]);
int days2 = Integer.parseInt(spl2[2]);
//make some calculation and in the end you can get the diffidence, this work i will let it for you.
This should solve your problem.
SimpleDateFormat myDateFormat = new SimpleDateFormat("yyyy-MM-dd");
List<Date> dateList = new ArrayList<Date>();
try {
beforeDate = myDateFormat.parse("2016-01-13");
dateList.add(myDateFormat.parse("2016-01-10"));
dateList.add(myDateFormat.parse("2016-01-11"));
dateList.add(myDateFormat.parse("2016-01-12"));
dateList.add(myDateFormat.parse("2016-01-19"));
dateList.add(myDateFormat.parse("2016-01-20"));
dateList.add(myDateFormat.parse("2016-01-21"));
} catch (ParseException e) {
System.out.println(e.getMessage());
}
//add here
boolean check = true;
for(int i = 0; check && i < dateList.size();i++){
if(dateList.get(i).after(beforeDate)){
afterDate = dateList.get(i);
check = false;
}
}
System.out.println(beforeDate+" "+afterDate);
long days = ChronoUnit.DAYS.between(LocalDate.parse(myDateFormat.format(beforeDate)), LocalDate.parse(myDateFormat.format(afterDate)));
if(days>0){
System.out.println(days);
}else{
System.out.println(0-days);
}
if you want to sort dateList then want to get afterDate then use this code after addition of date elements in dateList
Collections.sort(dateList,new Comparator<Date>() {
#Override
public int compare(Date o1, Date o2) {
return o1.compareTo(o2);
}
});
This will allow you to sort dates in ascending order..

"is this date the third thursday of the month?" - Java Library?

I've got a few dozen backlog requests in the pipeline like
'I need this functionality to run on the third Thursday of every month, and the first Wednesday of every other month...'
I've already got a function that runs every day, i just need the: isThirdSundayOfMonth(date) bit to append onto then end.
The less time I spend considering the nuances of the Gregorian calendar and timezones, the better my life is.
Anyone know a Java library that simplifies this sort of calculation? No xml config or frameworks or anything. Just a .Jar and a documented, readable API would be perfect.
Any help would be much appreciated.
Complete overview:
In Java-8 (new standard):
LocalDate input = LocalDate.now(); // using system timezone
int ordinal = 3;
DayOfWeek weekday = DayOfWeek.SUNDAY;
LocalDate adjusted =
input.with(TemporalAdjusters.dayOfWeekInMonth(ordinal, weekday));
boolean isThirdSundayInMonth = input.equals(adjusted);
In Joda-Time (popular 3rd-party-library):
LocalDate input = new LocalDate(); // using system timezone
int ordinal = 3;
int weekday = DateTimeConstants.SUNDAY;
LocalDate start = new LocalDate(input.getYear(), input.getMonthOfYear(), 1);
LocalDate date = start.withDayOfWeek(weekday);
LocalDate adjusted = (
date.isBefore(start))
? date.plusWeeks(ordinal)
: date.plusWeeks(ordinal - 1);
boolean isThirdSundayInMonth = input.equals(adjusted);
Using java.util.GregorianCalendar (old standard):
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
GregorianCalendar input = new GregorianCalendar();
int ordinal = 3;
int weekday = Calendar.SUNDAY;
GregorianCalendar start =
new GregorianCalendar(input.get(Calendar.YEAR), input.get(Calendar.MONTH), 1);
int dow = start.get(Calendar.DAY_OF_WEEK); // Sun=1, Mon=2, ...
int delta = (weekday - dow);
if (delta < 0) {
delta += 7;
}
start.add(Calendar.DAY_OF_MONTH, delta + (ordinal - 1) * 7);
String comp1 = sdf.format(input.getTime());
String comp2 = sdf.format(start.getTime());
boolean isThirdSundayInMonth = comp1.equals(comp2);
Even with the ugliest library a solution is possible ;-) I have used a string comparison in order to get rid of any timezone effects or time-of-day-parts including milliseconds. A field-wise comparison based only on year, month and day-of-month is also a good idea.
Using Time4J (my own 3rd-party-library):
PlainDate input =
SystemClock.inLocalView().today(); // using system timezone
Weekday weekday = Weekday.SUNDAY;
PlainDate adjusted =
input.with(PlainDate.WEEKDAY_IN_MONTH.setToThird(weekday));
boolean isThirdSundayInMonth = input.equals(adjusted);
The canonical library for all things date and time related is Joda Time. Adopt that and purge all the standard java classes like Date, Calendar, etc.
It will make your life much better.
As for "How do I use joda-time to find the third Thursday of the month", there's a stackoverflow answer for that already. I'd suggest using the code that the question asker posted and then the question "is it now the third Thursday of the month" is answered by:
LocalDate today = new LocalDate();
if (today.equals(calcDayOfWeekOfMonth(DateTimeConstants.THURSDAY, 3, today))) {
// do special third-Thursday processing here
}

get yesterday date from timestamp [duplicate]

This question already has answers here:
Get yesterday's date using Date [duplicate]
(8 answers)
Closed 8 years ago.
I've got an object with a field timestamp with type java.sql.Timestamp;.
And I need to get objects with yesterday date from a collection.
How to get them?
I mean I need something like this
for(int i = 0; i < items.size(); i++) {
(if the items.get(i).date == yesterday_date)
(get object)
}
You can get yesterday's Date by following approach Answered by Jiger Joshi.
And by using new Timestamp(java.util.Date) you can get yesterday's timestamp, you should use Timestamp#equals to equaling two different timestamp.
if (items.get(i).date.equals(getYesterdaytimestamp())){
...
}
And there are something which you must consider while implementing this. Calender#getTime which returns Date object and date object contains date with time, so in that case your equaling date or timestamp must be exactly equals with yesterday's date and time.
If requirement is, it needs to equal just yesterday no not where time is not considerable fact. In that case you need to equals two timestamp after discarding time part.
if (equalsWithYesterday(items.get(i).date)){
...
}
...
public boolean equalsWithYesterday(Timestamp st){
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd"); // Time part has discarded
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, -1);
Date yesterday = dateFormat.parse(dateFormat.format(cal.getTime())); // get yesterday's Date without time part
Date srcDate = new Date(st);
Date srcDateWithoutTime =dateFormat.parse(dateFormat.format(srcDate));
return yesterday.equals(srcDateWithoutTime ); // checks src date equals yesterday.
}
You can convert the timestamp object to date object like this:
Date date = new Date(items.get(i).getTime());
or you can simply use method Timestamp#compareTo(Date o)
items.get(i).compareTo(yesterday_date);
I hope you are not interested to compare the time?
Simply use Calendar class to extract the day, month, year etc. from the date and simply compare it.
Use Calendar#get() method to get the specific field from the date object.
How to subtract one day from the current date?
// get Calendar with current date
Calendar cal = Calendar.getInstance();
// get yesterday's date
cal.add(Calendar.DATE, -1);
// get components of yesterday's date
int month = cal.get(Calendar.MONTH) + 1; // 0 for January, 1 for Feb and so on
int day = cal.get(Calendar.DATE);
int year = cal.get(Calendar.YEAR);
// get yesterday's date in milliseconds
long lMillis = cal.getTime().getTime();

Convert String dates into Java Date objects [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicates:
Calculating difference in dates in Java
How can I calculate a time span in Java and format the output?
Say you were given two dates as strings and they are in this format 8/11/11 9:16:36 PM how would I go about converting them to java Date objects so that I can then calculate the difference between two dates?
As long as both times are in GMT/UTC, you can do date1.getTime() - date2.getTime() and then divide the result by 86400000 to get number of days. The rest is probably pretty intuitive.
EDIT -- based on edited question
To convert Strings into dates, use the SimpleDateFormat class.
String yourDateString = "8/11/11 9:16:36 PM";
SimpleDateFormat format =
new SimpleDateFormat("MM/dd/yy HH:mm:ss a");
Date yourDate = format.parse(yourDateString);
The majority of Date's getters are deprecated, replaced with Calendar methods. Here's how you would do it
Date date1, date2; //initialized elsewhere
Calendar day1 = new Calendar();
day1.setTime(date1)
Calendar day2 = new Calendar();
day2.setTime(date2);
int yearDiff, monthDiff, dayDiff, hourDiff, minuteDiff, secondDiff;
yearDiff = Math.abs(day1.get(Calendar.YEAR)-day2.get(Calendar.YEAR));
monthDiff = Math.abs(day1.get(Calendar.MONTH)-day2.get(Calendar.MONTH));
dayDiff = Math.abs(day1.get(Calendar.DAY_OF_YEAR)-day2.get(Calendar.DAY_OF_YEAR));
hourDiff = Math.abs(day1.get(Calendar.HOUR_OF_DAY)-day2.get(Calendar.HOUR_OF_DAY));
minuteDiff = Math.abs(day1.get(Calendar.MINUTE)-day2.get(Calendar.MINUTE));
secondDiff = Math.abs(day1.get(Calendar.SECOND)-day2.get(Calendar.SECOND));
Then you can do whatever you like with those numbers.
define a SimpleDateFormat matching your format (the java doc is pretty straighforward), then use the parse method to get a the proper Date object, from which you can easily compute the difference between the two dates.
Once you have this difference, the best is probably to compute "manually" the number of days / hours / minutes / seconds, although it might be possible to again use a SimpleDateFormat (or some other formatting mechanism) to display the proper values in a generic way.

Categories