我有这个有效的代码:
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)
如前所述,它可以工作,但是我对代码不满意,并试图做得更好。 有没有更好的方法来实现这一目标?
谢谢
答案 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)
Quarter
和YearQuarter
将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 ) ;