Get count day between to date Java

633 views Asked by At

Hello i need to get count day between to date using ChronoUnit

this is my code :

            Date madate = rfxobjet.getRv_rc_date();
            Date date=java.util.Calendar.getInstance().getTime();
            Date res=null;
            int day = ChronoUnit.DAYS.between(madate,date);

but i got this error : The method between(Temporal, Temporal) in the type ChronoUnit is not applicable for the arguments (Date, Date)

please what i should to do i need to resolve this error

3

There are 3 answers

1
igorpcholkin On BEST ANSWER

You mix different API. Date is an old class which was in Java since JDK 1. While ChronoUnit is from newer date API appeared first from JDK8. Normally you should use newer API. It means that instead of Date you should use LocalDate (or LocalDateTime) which is part of the new API.

So in order to correct your code you need to make so that madate and date are both instances of LocalDate. E.g. this should work:

LocalDate madate = LocalDate.now();
LocalDate date = LocalDate.now();
long day = ChronoUnit.DAYS.between(madate, date);

Or if you need still need to use Date objects you can convert them to Temporal objects:

Date madate = rfxobjet.getRv_rc_date();
Date date = java.util.Calendar.getInstance().getTime();
long day = ChronoUnit.DAYS.between(madate.toInstant(), date.toInstant());

Temporal is a base class for LocalDate and LocalDateTime so using Date.toInstant() you essentially convert date to corresponding instance in new API.

NB. between() returns long so the day variable also needs to be of type long or you need to use to int conversion:

int day = (int) ChronoUnit.DAYS.between(madate, date);
2
mohammedkhan On
Date madate = rfxobjet.getRv_rc_date();//please consider renaming this variable
LocalDate madataLocalDate = Instant.ofEpochMilli(madate.getTime()).atZone(ZoneId.systemDefault()).toLocalDate();
LocalDate now = LocalDate.now();
long day = ChronoUnit.DAYS.between(madataLocalDate, now);

Basically you need to use classes from the java.time package, you can't mix between java.util.Date and java.time.LocalDate.

0
Arvind Kumar Avinash On

You should stop using the outdated and error-prone java.util date-time API and switch to the modern date-time API.

If rfxobjet.getRv_rc_date() returns an object of java.util.Date, your first step should be to convert it into an object of type, Instant by calling Date#toInstant on this object i.e.

Date madate = rfxobjet.getRv_rc_date();
Instant instant = madate.toInstant();

Once you have an object of Instant, you can convert it to any other modern date-time object as per your requirement e.g.

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        Instant instant = Instant.now();
        // I've used the time-zone of Europe/London as an example, you can choose any
        // time-zone as per your requirement. You can also select the time-zone used by
        // your JVM, ZoneId.systemDefault()
        ZonedDateTime zdt = instant.atZone(ZoneId.of("Europe/London"));
        OffsetDateTime odt = zdt.toOffsetDateTime();
        LocalDateTime ldt = zdt.toLocalDateTime();
        System.out.println(instant);
        System.out.println(zdt);
        System.out.println(odt);
        System.out.println(ldt);
    }
}

Output:

2020-06-28T16:58:27.725618Z
2020-06-28T17:58:27.725618+01:00[Europe/London]
2020-06-28T17:58:27.725618+01:00
2020-06-28T17:58:27.725618

Note: LocalDateTime drops off information like Zone Offset and Zone ID which may be required in your business logic. Therefore, choose the appropriate class as per the table shown below (Ref): enter image description here

Back to your problem:

Now that you have an object of Instant, you can get an instance of LocalDateTime as described above i.e.

ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());
LocalDateTime ldt = zdt.toLocalDateTime();

The final step is to get the number of days between now and ldt which you can do as follows:

LocalDateTime now = LocalDateTime.now(ZoneId.systemDefault());
long days = ChronoUnit.DAYS.between(ldt, now);

Note that I've passed ZoneId as the parameter to LocalDateTime.now just as the recommended practice so that you can specify the required ZoneId as per your requirement. If you do not pass this parameter, it will use ZoneId.systemDefault() by default.

The complete code:

Date madate = rfxobjet.getRv_rc_date();
Instant instant = madate.toInstant();
ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());
LocalDateTime ldt = zdt.toLocalDateTime();
LocalDateTime now = LocalDateTime.now(ZoneId.systemDefault());
long days = ChronoUnit.DAYS.between(ldt, now);