1

I have a filter that is a String and can only accept 3 date-formats - YYYY, YYYY-MM, YYYY-MM-DD.

I want to check if the requested String is in the range of two dates.

Let's say, I have two dates (Instants) in a record - 2010-05-01T00:00:00Z & 2020-03-01TT23:59:59.999999999Z

Then:

Requested date | Range result

2018 | in range

2010 | in range

2009 | NOT in range

2018-03 | in range

2010-02 | NOT in range

2010-05 | in range (Thanks for the correction @Ole V.V.)

2012-01-05 | in range

2020-03-01 | in range

2020-04-01 | NOT in range

I am using Java time to check if a date is before or after the given dates, but in my case, I have a string that could be in any of the 3 date-formates.

One solution I can think of is if the request is YYYY, then only check if it is between years of the two dates. If the request is YYYY-MM, then check if it is between Year and month of the two dates. And so on. But I am not sure how to make it work.

Can someone please help to solve this problem?

AMagic
  • 2,690
  • 3
  • 21
  • 33
  • Have a look at the [java.time package](https://docs.oracle.com/en/java/javase/13/docs/api/java.base/java/time/package-summary.html), specifically the LocalDate, YearMonth, and Year classes. They all have isBefore and isAfter methods. – VGR Jan 22 '20 at 20:31
  • I think your example is not correct, can you please confirm your input outputs please? – Youcef LAIDANI Jan 22 '20 at 21:32
  • 2
    By the way… You might want to learn about the Half-Open approach to defining a span-of-time, where the beginning is *inclusive* and the ending is *exclusive*. This eliminates your split-second-at-the-end problem. – Basil Bourque Jan 22 '20 at 21:50
  • 1
    2010 is in your range? Some of the year is, some of it isn’t. So is it enough that a part of it is? Same for 2020-03-01. One nanosecond of the day is not. Is it an error that you say **2010-03 | in range**? The range doesn’t begin until a time in 2010-05. – Ole V.V. Jan 23 '20 at 15:21
  • You're right, it's an error in the question. I most likely overlooked to month value of the end date. – AMagic Jan 23 '20 at 16:45
  • 1
    @AMagic I would suggest to edit your question and put the correct info :) – Youcef LAIDANI Jan 23 '20 at 16:52

1 Answers1

3

You can create your own method to check if your date is valid of not, in your problem, you have three different cases, date which have only year, or date which have only year and month, or a full date, in this cases, you have a small problem when you want to parse the only the year, I can gives you this solution :

public static boolean isValid(String date, Instant start, Instant end) {
    LocalDate sld = start.atOffset(ZoneOffset.UTC).toLocalDate();
    LocalDate eld = end.atOffset(ZoneOffset.UTC).toLocalDate();
    try {
        LocalDate ld = LocalDate.parse(date);
        return ld.isAfter(sld) && ld.isBefore(eld);
    } catch (DateTimeParseException e) {}

    try {
        YearMonth ym = YearMonth.parse(date);
        return ym.isAfter(YearMonth.from(sld)) && ym.isBefore(YearMonth.from(eld));
    } catch (DateTimeParseException e) {}

    try {
        Year y = Year.parse(date);
        return y.isAfter(Year.from(sld)) && y.isBefore(Year.from(eld));
    } catch (DateTimeParseException e) {}
    return false;
}

Here is an Idemo demo

Youcef LAIDANI
  • 55,661
  • 15
  • 90
  • 140
  • Thanks, YCH_L, I like your approach. I will use your logic but may have to make slight change. – AMagic Jan 23 '20 at 16:47
  • What would you suggest if the start date and end date are not instant, but they are also two Strings of either of these 3 `YYYY`, `YYYY-MM`, `YYYY-MM-DD` formats? – AMagic Jan 23 '20 at 16:48
  • Yes exactly @AMagic, in can't make it in one patter which validate all the three format, for that I make it in steps, in the first step it will check if the format is `yyyy-MM-dd`, if not work it will move to the second case `yyyy-MM`, if not work it will move to the third case which is `yyyy` just the year, if no one can be correct then return false – Youcef LAIDANI Jan 23 '20 at 16:52
  • But when start & end date are also String and not Instant, what would you do? start date is `2010` end date is `2013-04` and request date is `2011-06-20`, so it's a match. Should I add this in my original question? – AMagic Jan 23 '20 at 16:59
  • 1
    @AMagic yes of course, my answer don't cover this specific case, I would suggest to create a new question which clarifying what other case you want to cover, and mention both question and answer in your new question and we will help you – Youcef LAIDANI Jan 23 '20 at 17:03
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/206530/discussion-between-amagic-and-ycf-l). – AMagic Jan 23 '20 at 17:44