30

I am trying to check in Java 8 if a date is older than 10 years and newer than 20 years. I am using Date.before() And Date.after() and passing currentDate-10 years and currentDate-20 years as arguments.

Can someone please suggest what will the cleanest way to get a date which is 10 year old and 20 years old in Date format to pass it in my before() and after() methods?

Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121
Andy897
  • 6,915
  • 11
  • 51
  • 86
  • I'm not 100% sure about this (never used date before/after), but have you tried comparing with a date initialised to today, then set another two dates with respect to this (10 years and 20 years before), then use those methods? – Aaa Dec 01 '15 at 07:23
  • 1
    heres a good read: http://www.oracle.com/technetwork/articles/java/jf14-date-time-2125367.html – Stultuske Dec 01 '15 at 07:24
  • 1
    http://stackoverflow.com/questions/883060/how-can-i-determine-if-a-date-is-between-two-dates-in-java – Stefan Dec 01 '15 at 07:26
  • Strongly recommend to not use java.util.Date and related classes. Use java.time.* – djeikyb Dec 07 '15 at 09:33
  • @Andy897 short answer: java.util.Date et al have lots of mutability and inheritance issues; `java.time` is its official replacement, by the authors of Joda Time. long answer: deserves an SO question if it doesn't already exist. – djeikyb Dec 21 '15 at 10:23

3 Answers3

40

You can use java.time.LocalDate to do this. Example: If you need to check if 01/01/2005 is between that duration, you can use

LocalDate date = LocalDate.of(2005, 1, 1); // Assign date to check
LocalDate today = LocalDate.now();

if (date.isBefore(today.minusYears(10)) && date.isAfter(today.minusYears(20))) {
  //Do Something
}
Jacob van Lingen
  • 8,989
  • 7
  • 48
  • 78
dkulkarni
  • 2,780
  • 4
  • 27
  • 36
  • 2
    I've taken the liberty of creating a separate variable to address the issue @SpaceTrucker raised. Feel free to roll back if you wish. Also, note that this answer ignores issues of *time* and *time zone*. I would probably truncate the time first using `atStartOfDay`, and time zone handling would depend on the specific use case. – jpmc26 Dec 01 '15 at 07:44
25

Using Calendar you can easily get a 10 year old date and 20 year old date from the current date.

Calendar calendar  = Calendar.getInstance();
calendar.add(Calendar.YEAR, -10);
Date d1 = calendar.getTime();
calendar.add(Calendar.YEAR, -10);
Date d2 = calendar.getTime();

As you are using Java 8 you can also use LocalDate

    LocalDate currentDate = LocalDate.now();
    Date d1 = Date.from(currentDate.minusYears(10).atStartOfDay(ZoneId.systemDefault()).toInstant());
    Date d2 = Date.from(currentDate.minusYears(20).atStartOfDay(ZoneId.systemDefault()).toInstant());

For comparing you can use the date.after() and date.before() methods as you said.

    if(date.after(d1) && date.before(d2)){  //date is the Date instance that wants to be compared
        ////
    }

The before() and after() methods are implemented in Calendar and LocalDate too. You can use those methods in those instances without converting into java.util.Date instances.

resueman
  • 10,572
  • 10
  • 31
  • 45
Ramesh-X
  • 4,853
  • 6
  • 46
  • 67
  • 8
    Although this works in java 8, I would recommend using the new date and time api. – SpaceTrucker Dec 01 '15 at 07:32
  • 1
    I thought OP wants to use `Date.after()` and `Date.before()` methods – Ramesh-X Dec 01 '15 at 10:01
  • I tried to compare Calendar with Date obj. (`cal.after(d1)`), and it returned `false` when compared cal. from 2019-07-08 to Date from 1970-01-01 (which obviously should return true). Solved it by converting my `d1` to Calendar. It seems like comparing cal+date does not work. Any idea why? – O-9 Jul 09 '19 at 10:09
  • @O95 If the argument of the `after()` method or `before()` method is not `Calendar` type, it will return `false`. See source code of [after()](https://github.com/openjdk-mirror/jdk7u-jdk/blob/master/src/share/classes/java/util/Calendar.java#L1974) and [before()](https://github.com/openjdk-mirror/jdk7u-jdk/blob/master/src/share/classes/java/util/Calendar.java#L1953) methods. – Ramesh-X Jul 09 '19 at 14:03
4

Another possibility is to get the year count between the date to check and the upper date. If the number of year is greater than 0 and less than 10, it means the date to check is older than 10 years and newer than 20 years.

This code will determine any date in the interval ]now - 20 years ; now - 10 years[:

public static void main(String[] args) {
    LocalDate dateToCheck = LocalDate.now().minusYears(20).plusDays(1);

    LocalDate upperYear = LocalDate.now().minusYears(10);
    long yearCount = ChronoUnit.YEARS.between(dateToCheck, upperYear);
    if (yearCount > 0 && yearCount < 10) {
        System.out.println("date is older than 10 years and newer than 20 years");
    }
}
Tunaki
  • 132,869
  • 46
  • 340
  • 423
  • 2
    I’d just use `long l=LocalDate.now().until(dateToCheck, ChronoUnit.YEARS); if(l<=-10 && l>-20)` if the task is “check whether the age is within that interval”. But your answer still is the only one not misguided by the XY style of the question that focuses on using `before` and `after` instead of the actual task. Note that `x.until(y, YEARS)` is the same as `YEARS.between(x, y)` but the latter delegates to the former. – Holger Dec 01 '15 at 11:48
  • 1
    @Holger There's a small detail however, I think this will check the interval `]now - 20 years ; now - 10 years]` (note the inclusive bound for the upper part). But the OP didn't say if the bounds were supposed to be included or not. – Tunaki Dec 01 '15 at 12:26
  • 1
    Well, you can choose the operators `>` or `>=` resp. `<` or `<=` as you like, but you don’t need intermediate `LocalDate` instances… – Holger Dec 01 '15 at 13:23
  • 1
    @Holger I think it's trickier. With `l<=-10 && l>-20`, the upper bound is included. But with `l<-10 && l>-20`, then for example a date one day before the upper bound will not be included (because `until` or `between` returns the number of complete years between the two dates). – Tunaki Dec 01 '15 at 13:31