【问题标题】:Calculate if today date between 2 other dates - But only with day and month [closed]计算今天的日期是否在其他 2 个日期之间 - 但仅限日期和月份 [关闭]
【发布时间】:2022-01-17 10:58:36
【问题描述】:

我的情况很奇怪, 我想计算一个日期是否在另外两个日期之间,但只有日期和月份。

示例(带 dd/mm):

  • 今天日期:17/01
  • FirstInterval : 01/11
  • SecondInterval : 19/01

应该是真的。

还有这个例子:

  • 今天日期:17/01
  • FirstInterval : 06/06
  • SecondInterval : 08/08

应该是假的

有没有简单的方法来解决这个问题?我真的不知道如何处理这些日期。

谢谢

【问题讨论】:

  • 看看java.time包和LocalDate等类和isBefore等方法
  • @f1sh,是的,这就是我正在使用的,但我的问题更多的是年份,例如第二个月是明年
  • @Cesar 处理月日时没有“明年”。

标签: java date


【解决方案1】:

使用java.time.MonthDay 类来表示日期。它具有isAfter()isBefore()compareTo() 等方法来比较两个实例。
一个问题是处理期间跨年变化的情况,即开始日期晚于结束日期。

    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));
        }
    }

由于isAfter()isBefore()MonthDays 相等时返回false,因此代码使用! isAfter() 而不是isBefore(),反之亦然。 (! isAfter() 将返回 true,如果 MonthDays 相等或者如果第一个 (this) 是 before 参数 - 数学上 x >= ynot(x < y) 相同)

【讨论】:

    【解决方案2】:

    这是一种方法:

    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));
      }
    

    测试:

        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);
    

    打印:

    true
    false
    

    尚未正确测试,但它应该可以工作。

    【讨论】:

    • 据我了解,OP 想要比较忽略年份的日期。我误会了吗?
    • 如果是这样,那么您可以在d2.isBefore(d1) 然后d2 = d2.plusYears(1) 时添加行,但这听起来很脆弱。
    • 好的。我调整了答案。
    • 它确实有效,使用这种方法,将第一个日期减去一年而不是第二个添加一年是明智的......谢谢!
    【解决方案3】:

    当省略年份时,FirstIntervalSecondInterval 之间的最大跨度为 12 个月。

    样本使用的日/月组合允许假设所有日期都在同一年。这意味着FirstInterval 可能永远不会大于SecondInterval,否则期限的结束必须在下一年。

    但在这种情况下,无法确定todayDate 是否适合该时期,因为它可能属于“本”年或“下”年(我们不知道哪个是正确的)。

    因此,为了能够获得确定性的输出,我们必须假设所有三个日期都是同一年。

    解决方案可能如下所示:

    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;
    }
    

    当然,这里缺少正确的错误处理,需要添加。

    但我们假设时间范围的含义类似于“一年中的季节”,我们想知道todayDate 是否在冬季。

    这样的解决方案可能如下所示:

    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;
    }
    

    【讨论】:

    • @user16320675 – 您完整阅读了我的回答?不,我假设……对于您的示例:12 月 12 日是否在范围内?没有年份,答案是 Yo 或 Nes - 你不能肯定地说。所以我的回答是基于输入数据的当前定义唯一合适的,对于计算机程序。您的样本是针对人类的……
    • @user16320675 – 规范是人为制定的,样本不是规范。 12 月 12 日在该范围内是因为您对该范围赋予了计算机无法使用的含义,并且在“规范”中未提及,这只是您的假设。
    【解决方案4】:

    将 3 个日期的日月提取为 6 个变量,例如: dd1、mm1、dd2、mm2、dd3 和 mm3。

    获得这些数字后,在 if 语句中进行简单的数字比较。

    【讨论】:

      猜你喜欢
      • 2019-07-10
      • 1970-01-01
      • 1970-01-01
      • 2021-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-03
      • 2021-05-17
      相关资源
      最近更新 更多