How to compare two dates created as JodaTime LocalDate and LocalDateTime? - java

LocalDate startDate = new LocalDate(2014,1,2);
LocalDateTime startDateTime = new LocalDateTime(2014,1,2,14,0);
I need to compare startDate and startDateTime with respect to the date, something like this:
// boolean equalDates = startDate.isequal(startDateTime.getDate());
Is it possible to do this?

If you just want to compare the date part, you can do it like so:
LocalDate startDate = new LocalDate(2014, 1, 2);
LocalDateTime startDateTime = new LocalDateTime(2014, 1, 2, 14, 0);
LocalDate forCompare = startDateTime.toLocalDate();
System.out.println("equal dates: " + forCompare.equals(startDate));
// equal dates: true
docs

LocalDate startDate = new LocalDate(2014,1,2);
LocalDateTime startDateTime = new LocalDateTime(2014,1,2,00,0);
System.out.println(startDate.toDate());
System.out.println(startDateTime.toDate());
if(startDate.toDate().compareTo((startDateTime.toDate()))==0){
System.out.println("equal");
}
the output will be:
Thu Jan 02 00:00:00 IST 2014
Thu Jan 02 00:00:00 IST 2014
equal

If you want to check if say one date is in between another time frame, say is date1 4hrs in between date2, joda has different classes just for those scenarios you can use:
Hours h = Hours.hoursBetween(date1, date2);
Days s = Days.daysBetween(date1, date2);
Months m = Months.monthsBetween(date1,date2);
http://joda-time.sourceforge.net/apidocs/org/joda/time/base/BaseSingleFieldPeriod.html

Related

Date difference in days for Java7

I have date formats as: EEE, dd MMM yyyy HH:mm:ss Z
For ex.,
Date 1 : Mon Sep 10 08:32:58 GMT 2018
Date 2 : Tue Sep 11 03:56:10 GMT 2018
I need date difference as 1 in above case, but I am getting value as 0 if I use joda date time or manually converting date to milliseconds.
For reference : http://www.mkyong.com/java/how-to-calculate-date-time-difference-in-java/
Any leads will be helpful.
Example :
Date date1 = new Date("Mon Sep 10 08:32:58 GMT 2018");
Date date2 = new Date("Tue Sep 11 03:56:10 GMT 2018");
DateTime start = new DateTime(date1 );
DateTime end = new DateTime(date2);
int days = Days.daysBetween(start, end).getDays();
System.out.println("Date difference: " + days);
Output: Date difference: 0
Joda-Time counts only whole days, in other words, truncates the difference to a whole number. So with a little over 19 hours between your values it counts as 0 days. If you want to ignore the time part of the dates, convert to LocalDate first:
int days = Days.daysBetween(start.toLocalDate(), end.toLocalDate()).getDays();
(Thanks for providing the concrete code yourself in a comment. Since you said it worked, I thought it deserved to be an answer.)
As mentioned in previous comments, Joda-Time counts whole days and rounds down. Therefore you'll need to skip the time when comparing. Something like this will work, using Java.time comparing the dates:
Date date1 = new Date("Mon Sep 10 08:32:58 GMT 2018");
Date date2 = new Date("Tue Sep 11 03:56:10 GMT 2018");
LocalDate start = date1.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
LocalDate end = date2.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
long between = ChronoUnit.DAYS.between(start, end);
System.out.println("Date difference: " + between);

How to get last week and last month with java8

I have a date and I need to know the last week and last month before the date.
For example,
on July 15, 2018, Its last week was from July 2 to July 8. Its last month was June 1 to June 30.
on July 16, 2018, Its last week was from July 9 to July 15. Its last month was June 1 to June 30.
on July 17, 2018, Its last week was from July 9 to July 15. Its last month was June 1 to June 30.
It is different from get-date-of-first-day-of-week-based-on-localdate-now-in-java-8, my problem is to get last week or last month.
You can use these helper methods.
public static LocalDate[] getPreviousWeek(LocalDate date) {
final int dayOfWeek = date.getDayOfWeek().getValue();
final LocalDate from = date.minusDays(dayOfWeek + 6); // (dayOfWeek - 1) + 7
final LocalDate to = date.minusDays(dayOfWeek);
return new LocalDate[]{from, to};
}
public static LocalDate[] getPreviousMonth(LocalDate date) {
final LocalDate from = date.minusDays(date.getDayOfMonth() - 1).minusMonths(1);
final LocalDate to = from.plusMonths(1).minusDays(1);
return new LocalDate[]{from, to};
}
There are in fact many ways to write this. I would suggest you to do some exploration on your own.
You can easly do that with Java 8 LocalDate, here's my solution:
import java.time.LocalDate;
LocalDate now = LocalDate.now();
LocalDate weekStart = now.minusDays(7+now.getDayOfWeek().getValue()-1);
LocalDate weekEnd = now.minusDays(now.getDayOfWeek().getValue());
LocalDate previousMonth = now.minusMonths(1);
LocalDate monthStart = previousMonth.withDayOfMonth(1);
LocalDate monthEnd = previousMonth.withDayOfMonth(previousMonth.getMonth().maxLength());
System.out.println("WeekStart:"+weekStart+", weekEnd:"+weekEnd+", monthStart:"+monthStart+", monthEnd:"+monthEnd);
Result
WeekStart:2018-07-09, weekEnd:2018-07-15, monthStart:2018-06-01, monthEnd:2018-06-30
If you change the now line with
LocalDate now = LocalDate.of(2018,07,15);
You'll get:
WeekStart:2018-07-02, weekEnd:2018-07-08, monthStart:2018-06-01, monthEnd:2018-06-30
ZonedDateTime is useful for that.
import java.time.*;
import java.time.format.DateTimeFormatter;
class DateTest
{
public static void main (String[] args) throws java.lang.Exception
{
DateTimeFormatter format = DateTimeFormatter.ofPattern("dd MMM yyyy");
ZoneId usCentral = ZoneId.of("America/Chicago");
LocalDateTime localDateTime = LocalDateTime.of(2018, Month.JULY, 16, 9, 30);
ZonedDateTime input = ZonedDateTime.of(localDateTime, usCentral);
System.out.println("Input date = " + format.format(input));
ZonedDateTime startDate = input.minusWeeks(1).with(DayOfWeek.MONDAY);
System.out.println("Start date = " + format.format(startDate));
ZonedDateTime endDate = startDate.plusDays(6);
System.out.println("End date = " + format.format(endDate));
}
}
Output:
Input date = 16 Jul 2018
Start date = 09 Jul 2018
End date = 15 Jul 2018
Not sure if you got a Date object, hopefully you got.
From date object you can get Instant with method toInstant()
(To pasrse String to date..
DateFormat format = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH);
Date date = format.parse(string);
date format must be addapted to your needs ofcourse
)
Instant.now().minus(Duration.ofDays(7))); // last week
Instant.now().minus(Duration.of(1,ChronoUnit.MONTHS)) // last month

java.util.date get milliseconds for y-m-d only

Situation: There is an Object AuditLog, which contains the variable java.util.Date date. This Object is saved in a mySQL Database.
#Entity
public class AuditLog implements Persistable<Long> {
...
#Temporal(TemporalType.DATE)
private Date date;
...
}
I am writing some JUnit tests and need to verify that a saved Date equals the actual date. Where date is a local Copy of the value actually passed to the log Object before it got saved and then loaded again.
Assert.assertEquals(date, log.getDate());
Output:
expected:<Wed May 24 15:54:40 CEST 2017> but was:<2017-05-24>
So you can see that the date actually is the right one but only y-m-d
I then tried this (below) to check if the milliseconds get altered.
Assert.assertEquals(date.getTime(), log.getDate().getTime());
Output:
expected:<1495634973799> but was:<1495576800000>
Now i think the best way would be to get the Milliseconds for year month day only.
Question: Can this be achieved relatively simple and should i do this? I think the Date gets altered because of a Database operation of some kind, so adapting the Test is OK right?
There are two ways to do this:
Using local date : You can convert util Date to LocalDate and do assertEquals on both the objects. LocalDate won't have time, e.g.:
Date input = new Date();
LocalDate date = input.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
System.out.println(date);
Using Apache commons' DateUtils: You can use truncate method to set non date fields to zero, e.g.:
Date input = new Date();
Date truncated = DateUtils.truncate(input, Calendar.DATE);
System.out.println(truncated);
Here's the maven dependency for Apache commons library.
You can get the "just the day, month, year by using the following code:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class Answer {
public static void main(String args[]) throws ParseException {
// parse the date and time
String input = "Wed May 24 15:54:40 CEST 2017";
SimpleDateFormat parser = new SimpleDateFormat("EEE MMM d HH:mm:ss zzz yyyy");
Date date = parser.parse(input);
// parse just the date
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
formatter.setTimeZone(TimeZone.getTimeZone("CEST"));
String formattedDate = formatter.format(date);
Date parsedDate = formatter.parse(formattedDate);
System.out.println(parsedDate);
// use https://currentmillis.com/ to check the milliseconds figures
System.out.println("Wed May 24 15:54:40 CEST 2017 in milliseconds \t" + date.getTime());
System.out.println("Wed May 24 00:00:00 CEST 2017 in milliseconds \t" + parsedDate.getTime());
}
}
The second SimpleDateFormat("yyyy-MM-dd"); parses on the year-month-day.
Use Date.getTime()); to get the milliseconds.
The output is:
Wed May 24 15:54:40 CEST 2017 in milliseconds 1495634080000
Wed May 24 00:00:00 CEST 2017 in milliseconds 1495584000000
1495584000000 = Wed May 24 2017 00:00:00 (using https://currentmillis.com/)
Calendar cal = GregorianCalendar.getInstance();
cal.set(Calendar.YEAR, 2017);
cal.set(Calendar.MONTH, 5 - 1);
cal.set(Calendar.DAY_OF_MONTH, 24);
cal.set(Calendar.MILLISECOND, 0);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
Date d = cal.getTime();
System.out.println(d.getTime());
this code creates a new java.util.Date with only year, month and day set. result of this example is 1495576800000 which is what you want.
A shorter way would be this:
Date d = new Date(0l);
d.setYear(117);
d.setMonth(4);
d.setDate(24);
d.setHours(0);
You should format the two dates:
Date date = new Date();
SimpleDateFormat dt = new SimpleDateFormat("yyyy-MM-dd");
dt.format(date);
Then compare each other.

Convert month name to Date range

I need to convert Monthname + Year to a valid date range. It needs to work with leap years etc.
Examples
getDateRange("Feb",2015)
should find the range 2015-02-01 -- 2015-02-28
While
getDateRange("Feb",2016)
should find the range 2016-02-01 -- 2016-02-29
In Java 8, you can do that using TemporalAdjusters,
LocalDate firstDate= date.with(TemporalAdjusters.firstDayOfMonth());
LocalDate lastDate= date.with(TemporalAdjusters.lastDayOfMonth());
If you have only year and month, it is better to use YearMonth. From YearMonth you can easily get length of that month.
YearMonth ym= YearMonth.of(2015, Month.FEBRUARY);
int monthLen= ym.lengthOfMonth();
Java 8 made Date-Time operations very simple.
For Java 7 and below you could get away with something like this;
void getDate(String month, int year) throws ParseException {
Date start = null, end = null;
//init month and year
SimpleDateFormat sdf = new SimpleDateFormat("MMM");
Date parse = sdf.parse(month);
Calendar instance = Calendar.getInstance();
instance.setTime(parse);
instance.set(Calendar.YEAR, year);
//start is default first day of month
start = instance.getTime();
//calculate end
instance.add(Calendar.MONTH, 1);
instance.add(Calendar.DAY_OF_MONTH, -1);
end = instance.getTime();
System.out.println(start + " " + end);
}
The output would be for "Feb", 2015:
Sun Feb 01 00:00:00 EET 2015
Sat Feb 28 00:00:00 EET 2015
Java 7 solution with default Java tools:
public static void getDateRange(String shortMonth, int year) throws ParseException {
SimpleDateFormat format = new SimpleDateFormat("MMM yyyy", Locale.ENGLISH);
// the parsed date will be the first day of the given month and year
Date startDate = format.parse(shortMonth + " " + year);
Calendar calendar = Calendar.getInstance();
calendar.setTime(startDate);
// set calendar to the last day of this given month
calendar.set( Calendar.DATE, calendar.getActualMaximum(Calendar.DATE));
// and get a Date object
Date endDate = calendar.getTime();
// do whatever you need to do with your dates, return them in a Pair or print out
System.out.println(startDate);
System.out.println(endDate);
}
Try (untested):
public List<LocalDate> getDateRange(YearMonth yearMonth){
List<LocalDate> dateRange = new ArrayList<>();
IntStream.of(yearMonth.lengthOfMonth()).foreach(day -> dateRange.add(yearMonth.at(day));
return dateRange
}
Java 8 provides new date API as Masud mentioned.
However if you are not working under a Java 8 environment, then lamma date is a good option.
// assuming you know the year and month already. Because every month starts from 1, there should be any problem to create
Date fromDt = new Date(2014, 2, 1);
// build a list containing each date from 2014-02-01 to 2014-02-28
List<Date> dates = Dates.from(fromDt).to(fromDt.lastDayOfMonth()).build();

Get all missing dates from the list of Dates (Sorted)

This could be a possible duplicate question
but still asking.
I have a list of date (dates are in unsorted)
1/5/2012,1/10/2012, 1/1/2012, 1/7/2012 (MM/dd/yyyy)( only date no timestamp)
First I sorted all dates using collections ref
Collections.sort(listOfDates);
Now listOfDates Contains dates in order. 1/1/2012, 1/5/2012, 1/7/2012, 1/10/2012
How can i get all missing dates from the sorted list?
missing dates -
1/2/2012
1/3/2012
1/4/2012
1/6/2012
1/8/2012
1/9/2012
I have a sample program , but not sure how to get it working with the above requirement
Sample Algo taken from this question
if (listOfDates!=null && !listOfDates.isEmpty()) {
Date firstDate = listOfDates.get(0) //contains the start date
Date lastDate = listOfDates.get(listOfDates.size()-1); //contains end date
}
Why not use the first and last dates in that sorted set to generate a list of dates between two dates? This answer uses jodaTime.
Use List-interfaces' removeAll -method with a list containing dates between your lowest (start date) and highest (end date) -values:
#Test
public void testAddMissingDates()
{
List<Date> listOfDates = new ArrayList<Date>();
//1/1/2012, 1/5/2012, 1/7/2012, 1/10/2012
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(0); //To zero out hour, minute, second ...
cal.set(2012, 0, 1); //Calendar.set: Month value is 0-based. e.g., 0 for January.
listOfDates.add(cal.getTime());
cal.set(2012, 0, 5);
listOfDates.add(cal.getTime());
cal.set(2012, 0, 7);
listOfDates.add(cal.getTime());
cal.set(2012, 0, 10);
listOfDates.add(cal.getTime());
Collections.sort(listOfDates);
List<Date> resultingDates = generateDateListBetween(listOfDates.get(0), listOfDates.get(listOfDates.size()-1));
//Remove all dates in listOfDates
resultingDates.removeAll(listOfDates);
for(Date date : resultingDates)
{
System.out.println(date);
}
}
private List<Date> generateDateListBetween(Date startDate, Date endDate)
{
//Flip the input if necessary, to prevent infinite loop
if(startDate.after(endDate))
{
Date temp = startDate;
startDate = endDate;
endDate = temp;
}
List<Date> resultList = new ArrayList<Date>();
Calendar cal = Calendar.getInstance();
cal.setTime(startDate);
do
{
resultList.add(cal.getTime());
cal.roll(Calendar.DAY_OF_MONTH, true); //Roll one day forwards
}
while(cal.getTime().before(endDate));
return resultList;
}
Output:
Mon Jan 02 02:00:00 EET 2012
Tue Jan 03 02:00:00 EET 2012
Wed Jan 04 02:00:00 EET 2012
Fri Jan 06 02:00:00 EET 2012
Sun Jan 08 02:00:00 EET 2012
Mon Jan 09 02:00:00 EET 2012
Write a method which takes two dates as argument and generates all the dates between these two dates. Now invoke this method for the sorted pair (example element i and i+1, and so on, the loop being from 0 to size of the list-1)of data in your sorted list.
Avoid legacy date-time types
Assuming you meant java.sql.Date objects, covert those to LocalDate objects. And sort.
List< LocalDate > dates =
inputs
.stream()
.map( java.sql.Date :: toLocalDate )
.sorted()
.toList() ;
Stream all dates in between first and last
Get the first and last dates. Make a stream of all dates in between. Filter those for dates not found amongst the originals.
List < LocalDate > missing =
dates.get( 0 )
.datesUntil( dates.get( dates.size() - 1 ) ) // Until last date
.filter( date -> ! dates.contains( date ) )
.toList() ;
Dump to console.
System.out.println( dates ) ;
System.out.println( missing ) ;
List#removeAll
Or, as commented by Mark Peters, use List#removeAll.
List < LocalDate > missing =
dates.get( 0 )
.datesUntil( dates.get( dates.size() - 1 ) ) // Until last date
.toList() ;
missing = new ArrayList<>( missing )
missing.removeAll( dates ) ; // Caution: Resulting list is modifiable.

Categories

Resources