简体   繁体   中英

Comparing dates in Java - only years, months and days

I'm trying to compare to dates object. Only one problem is that I want to compare just days, month and years.

/* toString output
mydate 2013-08-23
current date: Thu Aug 23 14:15:34 CEST 2013

If I compare just days ( 23-08-2013 ) dates are equal, if I'm using .after() .before() methods dates are diffrent.

Is there is Java method that compares only days, month, years in easy way or do I have to compare each value ?

Calendar cal1 = Calendar.getInstance();
Calendar cal2 = Calendar.getInstance();
cal1.setTime(date1);
cal2.setTime(date2);
boolean sameDay = cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
              cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR);

This will work perfectly.........

If you don't want to use external libraries and there is no problem using Calendar you could try something like this:

Calendar calendar1= Calendar.getInstance();
Calendar calendar2= Calendar.getInstance();

Date date1 = ...;
Date date2= ...;

calendar1.setTime(date1);
calendar1.set(Calendar.HOUR_OF_DAY, 0);
calendar1.set(Calendar.MINUTE, 0);
calendar1.set(Calendar.SECOND, 0);
calendar1.set(Calendar.MILLISECOND, 0);

calendar2.setTime(date2);
calendar2.set(Calendar.HOUR_OF_DAY, 0);
calendar2.set(Calendar.MINUTE, 0);
calendar2.set(Calendar.SECOND, 0);
calendar2.set(Calendar.MILLISECOND, 0);

calendar1.after(calendar2);
calendar1.before(calendar2);

Not so simple but is something...

Unfortunately, date support in the core Java API is very weak. You could use Calendar to strip time/timezone information from your date. You'd probably want to write a separate method to do that. You could also use the Joda API for date/time support, as it's much better than Java's.

Joda-Time is much better and highly recommended. But if you have to use Java api, you can do-

Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();

c1.setTime(someDate);
c2.setTime(someOtherDate);

int yearDiff = c1.get(Calendar.YEAR) - c2.get(Calendar.YEAR);
int monthDiff = c1.get(Calendar.MONTH) - c2.get(Calendar.MONTH);
int dayDiff = c1.get(Calendar.DAY_OF_MONTH) - c2.get(Calendar.DAY_OF_MONTH);

Say to compare only year, you can do-

if(c1.get(Calendar.YEAR) > c2.get(Calendar.YEAR)){
    // code
}

etc.

Date date = new Date();
String str="2013-08-23";
Date date=new SimpleDateFormat("yyyy-MM-dd").parse(str);

Calendar cal = Calendar.getInstance();
cal.setTime(date);
Calendar cal1 = Calendar.getInstance();
cal1.setTime(date1);

if(cal.get(Calendar.YEAR) == cal1.get(Calendar.YEAR)){
System.out.println("Years are equal");
}
else{
System.out.println("Years not equal");
}

if(cal.get(Calendar.MONTH) == cal1.get(Calendar.MONTH)){
System.out.println("Months are equal");
}
else{
System.out.println("Months not equal");
}

No there is nothing in the JDK. You could use some external library as Apache Commons Lang . There is a method DateUtils.isSameDay(Date, Date) which would do what you are looking for.

Better would be to avoid to use the Date of Java and use for instance JodaTime .

tl;dr

I want to compare just days, month and years.

mydate 2013-08-23

current date: Thu Aug 23 14:15:34 CEST 2013

If you want to capture the current date dynamically.

LocalDate.now(                   // Capture the current date…
    ZoneId.of( "Europe/Paris" )  // …as seen by the wall-clock time used by the people of a particular region (a time zone).
)
.isEqual(
    LocalDate.parse( "2013-08-23" ) 
)

Or, for a specific moment.

ZonedDateTime.of(  // Thu Aug 23 14:15:34 CEST 2013
    2013 , 8 , 23 , 14 , 15 , 34 , 0 , ZoneId.of( "Europe/Paris" )     
)
.toLocalDate()     // Extract the date only, leaving behind the time-of-day and the time zone.
.isEqual(
    LocalDate.parse( "2013-08-23" ) 
)

LocalDate

The bundled java.util.Date and .Calendar classes are notoriously troublesome. Avoid them. As other answers suggested, use a decent date-time libary. That means either:

You need to extract a date-only value from your date-time, to ignore the time-of-day. Both Joda-Time and java.time have such a class, coincidentally named LocalDate .

java.time

The java.time framework built into Java 8 and later supplants the old java.util.Date/.Calendar classes. The new classes are inspired by the highly successful Joda-Time framework, intended as its successor, similar in concept but re-architected. Defined by JSR 310 . Extended by the ThreeTen-Extra project. See the Tutorial .

ZoneId zoneId = ZoneId.of( "Europe/Paris" );

ZonedDateTime x = ZonedDateTime.of( 2014, 1, 2, 3, 4, 5, 6, zoneId );
ZonedDateTime y = ZonedDateTime.now( zoneId );

Extract and compare the date-only portion of the date-time by calling toLocalDate .

Boolean isSameDate = x.toLocalDate().isEqual( y.toLocalDate() );

Joda-Time

DateTimeZone timeZoneParis = DateTimeZone.forID( "Europe/Paris" );

DateTime x = new DateTime( 2014, 1, 2, 3, 4, 5, 6, timeZoneParis );
DateTime y = new DateTime( 2014, 6, 5, 4, 3, 2, 1, timeZoneParis );

boolean isXAfterY = x.isAfter( y );

To test equality of the date portion, convert the DateTime objects to a LocalDate which describes only a date without any time-of-day or time zone (other than a time zone used to decide the date).

boolean isSameDate = x.toLocalDate().isEqual( y.toLocalDate() );

If you want to examine the constituent elements, Joda-Time offers methods such as dayOfMonth , hourOfDay, and more.

How about this way

    String str="2013-08-23";
    Date date=new SimpleDateFormat("yyyy-MM-dd").parse(str);
    Calendar cal=Calendar.getInstance();
    cal.setTime(date);
    Calendar calNow=Calendar.getInstance();

    if(cal.get(Calendar.YEAR)>calNow.get(Calendar.YEAR)){
        // do something
    }if(cal.get(Calendar.MONTH)>calNow.get(Calendar.MONTH)){
        // do something
    }if(cal.get(Calendar.DATE)>calNow.get(Calendar.DATE)){
       // do something
    }

You can try this

    Date d1= ...
    Date d2= ...
    long dayInMillis = 24 * 3600 * 1000; 
    boolean dateEqual = d1.getTime() / dayInMillis == d2.getTime() / dayInMillis;  

The solution to this problem is surprisingly simple. You'll need to begin by parsing your date time strings into Date instants in the Java API (you can use a SimpleDateFormat object to help you do this).

If you have two instants in time represented as Dates:

  1. Get the representation of both as long integers
  2. Because all Dates are represented internally in UTC, adjust both to the local time zone by adding or substracting the offsets from GMT +/- DST
  3. Convert both to an integer count of days (which will include the granularity for comparing years and months)
  4. Compare them by their natural order; if the integers are equal, the day, month, and year are equal irrespective of local time (assuming, of course, that both Date instants were in the same time zone).

Presto!

A method for adjusting a Date object to local time and returning it as a decimal count of days in the POSIX Epoch follows:

public static double toLocalDayNumber(Date d, GregorianCalendar gc) {

        gc.setTime(d);

        long utcDateAsMillisFromEpoch = gc.getTimeInMillis();
        long localDateAsMillisFromEpoch = utcDateAsMillisFromEpoch +
                gc.get(GregorianCalendar.ZONE_OFFSET) +
                gc.get(GregorianCalendar.DST_OFFSET);

        return (((double) localDateAsMillisFromEpoch) / (86400.0 * 1000.0);
}

This method takes a Date object d , and a Java API Calendar object gc that has been constructed with the local TimeZone of interest.

By using Date only

        SimpleDateFormat cDate1 = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
        Date now1 = new Date();
        String ccDate1 = cDate1.format(now1);
        System.out.println("Date1=="+ccDate1);


        SimpleDateFormat cDate2 = new SimpleDateFormat("yyyy-MM-dd HH-mm-sss");
        Date now2 = new Date();
        String ccDate2 = cDate2.format(now2);
        System.out.println("Date2=="+ccDate2);

        if(ccDate1.equals(ccDate2))//Get full feature of date
            System.out.println("Equal");
        else
            System.out.println("Not Equal");

        if(ccDate1.split(" ")[0].equals(ccDate2.split(" ")[0]))//Comparing  Full Date
            System.out.println("Equal");
        else
            System.out.println("Not Equal");

        if(ccDate1.split(" ")[0].split("-")[0].equals(ccDate2.split(" ")[0].split("-")[0]))//Comparing YEAR
            System.out.println("Equal");
        else
            System.out.println("Not Equal");

        if(ccDate1.split(" ")[0].split("-")[1].equals(ccDate2.split(" ")[0].split("-")[1]))//Comparing MONTH
            System.out.println("Equal");
        else
            System.out.println("Not Equal");

        if(ccDate1.split(" ")[0].split("-")[2].equals(ccDate2.split(" ")[0].split("-")[2]))//Comparing DAY
            System.out.println("Equal");
        else
            System.out.println("Not Equal");

An example using Java Calendar to compare only the date parts between 2 calendar objects without having to clear() all other calendar fields (MINUTE, MILLISECOND, etc), which gets set when Calendar.getInstance() is called.

I know this thread is old, and this is not a new solution but might be of help to some people.

Calendar cal1 = Calendar.getInstance();
Calendar cal2 = Calendar.getInstance();

cal1.set(2018, Calendar.JANUARY, 1);
cal2.set(2018, Calendar.JANUARY, 1);

System.out.println(_doesCalendar1DateMatchCalendar2Date(cal1,cal2)); // in this case returns true

private boolean _doesCalendar1DateMatchCalendar2Date(Calendar cal1, Calendar cal2) {
            boolean sameDate = cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) 
                    && cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH)
                    && cal1.get(Calendar.DATE) == cal2.get(Calendar.DATE);
            return sameDate;
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM