Home > OS >  Calculate if today date between 2 other dates - But only with day and month
Calculate if today date between 2 other dates - But only with day and month

Time:01-17

I'm in a weird situation, I want to calculate if a date is between 2 other date, but only with day and month.

Example (with dd/mm) :

  • today date : 17/01
  • FirstInterval : 01/11
  • SecondInterval : 19/01

Should be TRUE.

And this example :

  • today date : 17/01
  • FirstInterval : 06/06
  • SecondInterval : 08/08

Should be FALSE

Is there a simple method to deal with this ? I don't really know how to deal with years with those dates.

Thanks

CodePudding user response:

Use the java.time.MonthDay class to represent the dates. It has methods like isAfter(), isBefore() and compareTo() to compare two instances.
One problem is handling the case when the period covers a year change, that is, when the start date is after the end date.

    boolean checkInterval(String testDate, String startDate, String endDate) {
        var format = DateTimeFormatter.ofPattern("dd/MM");
        var test = MonthDay.parse(testDate, format);
        var start = MonthDay.parse(startDate, format);
        var end = MonthDay.parse(endDate, format);

        if (end.isBefore(start)) {
            // end must be in *next* year
            return !(test.isBefore(start) && test.isAfter(end));
        } else {
            // start and end on same year
            return !(test.isBefore(start) || test.isAfter(end));
        }
    }

Since isAfter() and isBefore() returns false if the MonthDays are equal, the code is using ! isAfter() instead of isBefore() and vice-versa. (! isAfter() will return true if the MonthDays are equal or if the first (this) is before the argument - mathematically x >= y is the same as not(x < y))

CodePudding user response:

Thats one way of doing it:

boolean isDateBetween(String dateToTest, String lowerDate, String upperDate) {
    int anyYear = 2000;
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
    LocalDate d1 = LocalDate.parse(lowerDate   "/"   anyYear, formatter);
    LocalDate d2 = LocalDate.parse(upperDate   "/"   anyYear, formatter);
    if (d2.isBefore(d1)) {
      d1 = d1.minusYears(1);
    }
    LocalDate testDate = LocalDate.parse(dateToTest   "/"   anyYear, formatter);
    return testDate.isEqual(d1) || testDate.isAfter(d1) && (testDate.isEqual(d2) || testDate.isBefore(d2));
  }

Test:

    boolean result1 = isDateBetween("17/01", "01/11", "19/01");
    boolean result2 = isDateBetween("17/01", "06/06", "07/08");
    System.out.println(result1);
    System.out.println(result2);

Prints:

true
false

Haven't tested it properly, but it should work.

CodePudding user response:

Extract the day and month of the 3 dates into 6 variables such as: dd1, mm1, dd2, mm2, dd3 and mm3.

Once you have those numbers, do a simple number comparison in an if statement.

CodePudding user response:

When the year is omitted, the maximum span between FirstInterval and SecondInterval is 12 month.

The samples are using day/month combinations that allows the assumption that all dates are in the same year. This means that the FirstInterval may never be greater than SecondInterval, otherwise the end of the period must be in the following year.

But in that case, it is impossible to determine whether the todayDate fits into the period because it may belong to "this" year or to the "following" year (and we don't know which is right).

So to be able to get a deterministic output, we have to assume that all three dates are for the same year.

A solution may look like this:

public final boolean isDateBetween( final String todayDate, final String firstInterval, final String secondInterval ) 
{
  var formatter = DateTimeFormatter.ofPattern("dd/MM");
  var lowerRange = MonthDay.parse( firstInterval, formatter );
  var upperRange = MonthDay.parse( secondInterval, formatter );
  if( !upperRange.isAfter( lowerRange ) ) throw new Error();
  var testDate = MonthDay.parse( todayDate, formatter );

  var retValue = !testDate.isBefore( lowerRange ) && !testDate.isAfter( upperRange );

  return retValue;
}

Of course, a proper error handling is missing here and needs to be added.

But let's assume that the time range has a meaning like "Season of the Year", and we want to know if a todayDate is in Winter or not.

Such a solution may look like this:

public final boolean isDayInSeason( final String today, final String begin, final String end ) 
{
  boolean retValue = false;
  var formatter = DateTimeFormatter.ofPattern("dd/MM");
  var lowerRange = MonthDay.parse( begin, formatter );
  var upperRange = MonthDay.parse( end, formatter );
  if( !upperRange.isAfter( lowerRange ) )
  {
     retValue = isDayInSeason( today, lowerRange, "31/12" ) || isDayInSeason( today, "01/01", upperRange );
  }
  else
  {
     var testDate = MonthDay.parse( todayDate, formatter );
     retValue = !testDate.isBefore( lowerRange ) && !testDate.isAfter( upperRange );
  }
  return retValue;
}
  •  Tags:  
  • Related