确定季度边界日期的更好方法

时间:2019-06-14 09:20:10

标签: java date kotlin

我有这个有效的代码:

sandbox.stub(debounce).returnsArg(0);

此代码采用一个循环编号:1或2或3或4以及一年 并返回2个日期的数组(季度的开始和结束)

例如,如果我致电:

    private fun getCycleBoundaries(cycleNumber: Int, year: Int): Array<Date> {

        return when (cycleNumber) {
            1 -> arrayOf(DATE_FORMATER.parse("$year-01-01T00:00:00"), DATE_FORMATER.parse("$year-03-31T23:59:59"))
            2 -> arrayOf(DATE_FORMATER.parse("$year-04-01T00:00:00"), DATE_FORMATER.parse("$year-06-30T23:59:59"))
            3 -> arrayOf(DATE_FORMATER.parse("$year-07-01T00:00:00"), DATE_FORMATER.parse("$year-09-30T23:59:59"))
            4 -> arrayOf(DATE_FORMATER.parse("$year-10-01T00:00:00"), DATE_FORMATER.parse("$year-12-31T23:59:59"))
            else -> throw IllegalArgumentException("$cycleNumber is nor a valid cycle number")
        }
    }

我希望:

 getCycleBoundaries(1, 2019)

如前所述,它可以工作,但是我对代码不满意,并试图做得更好。 有没有更好的方法来实现这一目标?

谢谢

2 个答案:

答案 0 :(得分:3)

java.time的IsoFields类可能会被忽略。在处理宿舍方面,这是我们的朋友。抱歉,我只能编写Java代码。

public static LocalDate[] getCycleBoundaries(int cycleNumber, int year) {
    YearMonth firstMonthOfQuarter = YearMonth.of(year, 1)
            .with(IsoFields.QUARTER_OF_YEAR, cycleNumber);
    return new LocalDate[] { firstMonthOfQuarter.atDay(1),
            firstMonthOfQuarter.plusMonths(2).atEndOfMonth() };
}

让我们尝试一下:

    System.out.println(Arrays.toString(getCycleBoundaries(4, 2019)));

在这种情况下的输出:

  

[2019-10-01,2019-12-31]

提示:使用半开间隔。尽管用户通常更喜欢在日历的第一天和最后一天给出一个句点,但是在计算机程序中,通常更方便地将句点表示为 from date 日期排他。因此,将一个季度作为该季度的第一天和下一个季度的第一天。而且,如果您已经知道该期间是一个季度,那么就只是该季度的第一天,仅此而已。其余的可以根据需要轻松计算。

答案 1 :(得分:1)

QuarterYearQuarter

ThreeTen-Extra库添加到您的项目中。您可以访问方便的类,这些类扩展了Java内置并在JSR 310中定义的现代 java.time 类的功能。

Quarter枚举类表示不带年份的通用季度。在您的代码中使用此类,而不是仅使用整数1-4。这样听起来就可以使您的代码更具自记录性,提供类型安全性并确保有效值。

Quarter q = Quarter.Q2 ;

YearQuarter代表特定年份的四分之一。

YearQuarter yq = YearQuarter.of( 2019 , q ) ;

获取该季度第一天的日期。

LocalDate start = yq.atDay( 1 ) ;

获取季度的最后一天的日期。

LocalDate lastDate = yq.atEndOfQuarter() ;

或者对于半开放日期范围,获取下一个季度的第一天。

LocalDate stop = yq.plusQuarters( 1L ).atDay( 1 ) ;

使用返回的日期数组,而不是仅返回日期数组,而是使用 ThreeTen-Extra 中包含的LocalDateRange类。此类提供了强大的比较方法,例如包含,邻接,重叠等。

LocalDateRange qDates = LocalDateRange.of( start , stop ) ;