仅使用数值 months 查询月内的日期

Querying dates within months using only numerical values months

提问人:oldcode 提问时间:5/15/2023 最后编辑:oldcode 更新时间:6/17/2023 访问量:203

问:

我有 2 个日期值和一组行,其范围定义为 和 。目前的情况是,我只有如下所示的月份信息,没有年份数据可以将输入的 2 个日期值与这些月份进行比较。discount_start_monthdiscount_end_month

目标是获取日期并查看它们属于哪个月份范围。在任何给定时间点,它们都可能属于以下任何一种情况discount_code

例如:日期为 2022 年 1 月 1 日。 2021 年 12 月 1 日的日期仍将到来DEC_JANDEC_JAN

问题:

  1. 问题陈述是没有年份信息,您将如何检查输入日期在哪个范围内?
  2. 一旦我弄清楚 (1),我需要生成 2 个日期,其值为 和 ,因此对于上述内容,它将是 ,advance_start_monthadvance_end_month

2 个日期将被命名为 和startDateGenerationendDateGeneration

startDateGeneration将从 的 ,discount_codeadvance_start_month

考虑 2022 年 1 月 1 日的示例,将从 和startDateGenerationDEC_JANadvance_start_monthadvance_end_month

天 -> 10 月的第一天(从advance_start_month)

月份 -> 10月

年份 -> 上一年

startDateGeneration将是 2021年10月1日

同样,我们将使用 所以它将是 2022 年 1 月 1 日endDateGenerationadvance_end_month

enter image description here

输入为开始日期和结束日期

通过循环访问上述数据集来查找范围内日期的代码。

private static boolean isInRange(
      LocalDate discountDate, Integer fromMonth, Integer toMonth) {
    YearMonth fromMonthDiscount = YearMonth.of(discountDate.getYear(), fromMonth);
    YearMonth toMonthDiscount = YearMonth.of(discountDate.getYear(), toMonth);
    YearMonth yearMonthDiscountDate =
        YearMonth.of(discountDate.getYear(), discountDate.getMonthValue());

    if (fromMonth > toMonth) {
      if (discountDate.getMonthValue() == Constants.DEC_MONTH) {
        toMonthDiscount = YearMonth.of(discountDate.getYear() + 1, toMonth);
      } else if (discountDate.getMonthValue() == Constants.JAN_MONTH) {
        fromMonthDiscount = YearMonth.of(discountDate.getYear() - 1, fromMonth);
      }
    }

    return (yearMonthDiscountDate.isAfter(fromMonthDiscount)
            || yearMonthDiscountDate.equals(fromMonthDiscount))
        && (yearMonthDiscountDate.isBefore(toMonthDiscount)
            || yearMonthDiscountDate.equals(toMonthDiscount));
  }

找到问题陈述(2)部分的逻辑,

 int startYear = fromDate.getYear();
    int endYear = toDate.getYear();
    
    // Get the advance_start_month from the DB iterating object of the start date
    int advanceStartMonth = ....
    
    if(advanceStartMonth >= Constants.OCT_MONTH &&
        advanceStartMonth <= Constants.DEC_MONTH &&
        startYear == endYear) {
        startYear = startYear - 1;
    }
    
    // Get the advance_start_month and advance_end_month from the DB iterating object of the end date  
    int discountResultStartMonth = //.......
        int discountResultEndMonth = //........
    
        if (discountResultStartMonth > discountResultEndMonth) {
            if (toDate.getMonthValue() == Constants.DEC_MONTH) {
                endYear = endYear + 1;
            }
        }

形成日期以从中生成范围的逻辑,

fromDateSeasonMap-> 上述数据集中 1 行的数据集(用于开始日期) -> 来自上述数据集的 1 行数据集(用于结束日期)toDateSeasonMap

LocalDate startDateGeneration =
          fromDate
              .withMonth((Integer) fromDateSeasonMap.get(Constants.ADVANCE_START_MONTH))
              .withYear(startYear);
      LocalDate endDateGeneration =
          toDate
              .withMonth((Integer) toDateSeasonMap.get(Constants.ADVANCE_END_MONTH))
              .withYear(endYear)
              .withDayOfMonth(
                  YearMonth.of(endYear, (Integer) toDateSeasonMap.get(Constants.ADVANCE_END_MONTH))
                      .atEndOfMonth()
                      .getDayOfMonth());

笔记:

  1. 在任何给定时间点,数据集中都不会有重叠的月份。
  2. 仅存在月份数值数据。
  3. 不会有大于 12 的值,因为一年只有 12 个月。

预期输入和输出

Begin Input
Start Date: 2023-08-01
End Date: 2023-10-01
startDateGeneration: 2023-06-01
endDateGeneration: 2023-11-30
===================================
Begin Input
Start Date: 2023-09-01
End Date: 2023-12-01
startDateGeneration: 2023-07-01
endDateGeneration: 2024-01-31
===================================
Begin Input
Start Date: 2023-01-30
End Date: 2023-02-01
startDateGeneration: 2022-11-30
endDateGeneration: 2023-03-31
===================================
Begin Input
Start Date: 2023-01-30
End Date: 2023-02-01
startDateGeneration: 2022-11-30
endDateGeneration: 2023-03-31
===================================
Begin Input
Start Date: 2022-10-30
End Date: 2023-02-01
startDateGeneration: 2022-08-30
endDateGeneration: 2023-03-31
===================================
Begin Input
Start Date: 2022-08-30
End Date: 2022-10-01
startDateGeneration: 2022-06-30
endDateGeneration: 2022-12-31
===================================
Begin Input
Start Date: 2022-08-30
End Date: 2023-02-01
startDateGeneration: 2022-06-30
endDateGeneration: 2023-03-31
===================================
Begin Input
Start Date: 2023-04-30
End Date: 2023-07-01
startDateGeneration: 2023-02-28
endDateGeneration: 2023-07-31
===================================
Begin Input
Start Date: 2023-06-30
End Date: 2023-07-01
startDateGeneration: 2023-04-30
endDateGeneration: 2023-07-31
===================================
Begin Input
Start Date: 2023-08-30
End Date: 2023-10-01
startDateGeneration: 2023-06-30
endDateGeneration: 2023-12-31
===================================
Begin Input
Start Date: 2023-10-30
End Date: 2024-01-01
startDateGeneration: 2023-08-30
endDateGeneration: 2024-03-31
===================================
Begin Input
Start Date: 2022-12-30
End Date: 2023-02-01
startDateGeneration: 2022-10-30
endDateGeneration: 2023-03-31
===================================
Begin Input
Start Date: 2023-01-30
End Date: 2023-02-01
startDateGeneration: 2022-10-30
endDateGeneration: 2023-03-31
===================================
Begin Input
Start Date: 2022-10-01
End Date: 2023-02-01
startDateGeneration: 2022-07-01
endDateGeneration: 2023-03-31
===================================
Begin Input
Start Date: 2022-12-01
End Date: 2023-02-01
startDateGeneration: 2022-10-01
endDateGeneration: 2023-03-31
===================================
Begin Input
Start Date: 2023-02-01
End Date: 2023-04-01
startDateGeneration: 2022-12-01
endDateGeneration: 2023-05-31
===================================
Begin Input
Start Date: 2023-02-01
End Date: 2023-03-01
startDateGeneration: 2022-12-01
endDateGeneration: 2023-03-31
===================================
Begin Input
Start Date: 2023-04-30
End Date: 2023-06-01
startDateGeneration: 2023-02-28
endDateGeneration: 2023-07-31
===================================
Begin Input
Start Date: 2023-06-30
End Date: 2023-08-01
startDateGeneration: 2023-04-30
endDateGeneration: 2023-08-31
===================================
java 日期 localdate yearmonth

评论

1赞 Anonymous 5/15/2023
对不起,我无法关注。我想我需要具有代表性的示例输入和所需输出。
0赞 oldcode 5/15/2023
@OleV.V.开始日期和结束日期是输入,预期输出是 和startDateGenerationendDateGeneration
0赞 oldcode 5/15/2023
@OleV.V.让我知道这是否有帮助,或者您是否需要更多详细信息
1赞 kriegaex 5/29/2023
实现您需要的逻辑可能非常容易。然而,我不禁想知道为什么有人会这样用自己的脚开枪,让一件简单的事情变得复杂。为什么不使用实际日期而不是月份和“季节”的奇怪组合来指定折扣期的开始和结束?是否有人认为这还不够复杂,然后故意让它变得更难?
1赞 kriegaex 5/29/2023
此外,您从未解释过季节如何转化为年份以及提前日期的实际含义。似乎提前开始月份总是在折扣开始前两个月,而提前结束总是与折扣结束相同。因此,您可以自动计算它们。谁设计了这样的系统?也许是受虐狂——没有冒犯的意思。

答:

0赞 1 1 5/30/2023 #1
private static boolean isInRange(
    LocalDate discountDate, Integer fromMonth, Integer toMonth) {
  int discountYear = discountDate.getYear();

  if (fromMonth > toMonth) {
    if (discountDate.getMonthValue() == Constants.DEC_MONTH) {
      toMonth += 12;
    } else if (discountDate.getMonthValue() == Constants.JAN_MONTH) {
      fromMonth -= 12;
    }
  }

  return discountDate.getMonthValue() >= fromMonth && discountDate.getMonthValue() <= toMonth;
}

int startYear = fromDate.getYear();
int endYear = toDate.getYear();
int advanceStartMonth = fromDateSeasonMap.get(Constants.ADVANCE_START_MONTH);
int advanceEndMonth = toDateSeasonMap.get(Constants.ADVANCE_END_MONTH);

if (advanceStartMonth >= Constants.OCT_MONTH && advanceStartMonth <= Constants.DEC_MONTH && startYear == endYear) {
  startYear -= 1;
}

if (advanceEndMonth >= Constants.OCT_MONTH && advanceEndMonth <= Constants.DEC_MONTH && startYear == endYear) {
  endYear -= 1;
}

if (advanceEndMonth < advanceStartMonth) {
  if (toDate.getMonthValue() == Constants.DEC_MONTH) {
    endYear += 1;
  }
}

LocalDate startDateGeneration = fromDate.withMonth(advanceStartMonth).withYear(startYear);
LocalDate endDateGeneration = toDate.withMonth(advanceEndMonth).withYear(endYear);

// Adjust the end day of the month for endDateGeneration
int lastDayOfMonth = YearMonth.of(endYear, advanceEndMonth).lengthOfMonth();
endDateGeneration = endDateGeneration.withDayOfMonth(lastDayOfMonth);

希望对您有所帮助,问题不是很清楚,但这可以帮助您。

评论

0赞 Community 5/30/2023
您的答案可以通过其他支持信息进行改进。请编辑以添加更多详细信息,例如引文或文档,以便其他人可以确认您的答案是正确的。您可以在帮助中心找到有关如何写出好答案的更多信息。
0赞 I.sh. 5/30/2023 #2

要处理开始月份大于结束月份的逻辑,可以按如下方式修改逻辑:isInRange

private static boolean isInRange(LocalDate discountDate, Integer fromMonth, Integer toMonth) {
    int discountYear = discountDate.getYear();
    int discountMonth = discountDate.getMonthValue();

    if (fromMonth <= toMonth) {
        return discountMonth >= fromMonth && discountMonth <= toMonth;
    } else {
        if (discountMonth >= fromMonth || discountMonth <= toMonth) {
            return true;
        } else {
            if (discountMonth == Constants.JAN_MONTH && toMonth == Constants.DEC_MONTH) {
                return true;
            }
            if (discountMonth == Constants.DEC_MONTH && fromMonth == Constants.JAN_MONTH) {
                return true;
            }
        }
    }

    return false;
}

此逻辑通过考虑 12 月 (12) 和 1 月 (1) 的特殊情况来处理开始月份大于结束月份的情况。

若要处理基于数据集的年份生成逻辑,可以使用以下方法:

  1. 从对象中获取起始年份。fromDate
  2. 从对象中获取结束年份。toDate
  3. 从数据集中检索 and。advance_start_monthadvance_end_month
  4. 检查 10 月 (10 日) 和 12 月 (12 日)之间(含)是否介于两者之间,并且开始年份与结束年份相同。如果为 true,则将起始年份递减 1。advance_start_month
  5. 检查 是否小于 .如果为 true,请检查月份是否为 12 月 (12),并将结束年份递增 1。advance_end_monthadvance_start_monthtoDate

下面是年份生成逻辑的示例实现:

int startYear = fromDate.getYear();
int endYear = toDate.getYear();

// Get the advance_start_month from the DB iterating object of the start date
int advanceStartMonth = ...; // Retrieve the value from the dataset

if (advanceStartMonth >= Constants.OCT_MONTH && advanceStartMonth <= Constants.DEC_MONTH && startYear == endYear) {
    startYear = startYear - 1;
}

// Get the advance_start_month and advance_end_month from the DB iterating object of the end date
int advanceEndMonth = ...; // Retrieve the value from the dataset

if (advanceEndMonth < advanceStartMonth) {
    if (toDate.getMonthValue() == Constants.DEC_MONTH) {
        endYear = endYear + 1;
    }
}

通过遵循此方法,您可以为 and 对象生成正确的开始年份和结束年份。startDateGenerationendDateGeneration

请注意,您需要从数据集中检索相应的值,如代码注释中所述。advance_start_monthadvance_end_month

我希望我正确地理解了这个问题,这很难理解。