完善季度相关 API(pr#1324@Gitee)

This commit is contained in:
Looly 2025-03-31 10:04:32 +08:00
parent 6496cd20cf
commit 1b29100fb3
4 changed files with 70 additions and 104 deletions

View File

@ -2,7 +2,7 @@
# 🚀Changelog
-------------------------------------------------------------------------------------------------------------
# 5.8.37(2025-03-24)
# 5.8.37(2025-03-31)
### 🐣新特性
* 【json 】 ObjectMapper删除重复trimpr#3859@Github
@ -16,6 +16,7 @@
* 【core 】 改进`PropDesc`中去除Transient引用避免NoClassDefFoundErrorissue#3901@Github
* 【core 】 `StrUtil.isBlank`增加`\u200c`判断issue#3903@Github
* 【core 】 优化`CombinationAnnotationElement`注解数组性能pr#1323@Gitee
* 【core 】 完善季度相关 APIpr#1324@Gitee
### 🐞Bug修复
* 【setting】 修复`SettingLoader`load未抛出异常导致配置文件无法正常遍历的问题pr#3868@Github

View File

@ -1,11 +1,11 @@
package cn.hutool.core.date;
import cn.hutool.core.lang.Assert;
import java.time.DateTimeException;
import java.time.MonthDay;
import java.time.temporal.ChronoField;
import cn.hutool.core.lang.Assert;
/**
* 季度枚举
*
@ -41,6 +41,11 @@ public enum Quarter {
this.firstMonth = lastMonth - 2;
}
/**
* 获取季度值
*
* @return 季度值
*/
public int getValue() {
return this.value;
}
@ -54,7 +59,7 @@ public enum Quarter {
* @see #Q4
*
* @param intValue 季度int表示
* @return {@link Quarter}
* @return {@code Quarter}
*/
public static Quarter of(int intValue) {
switch (intValue) {
@ -116,20 +121,11 @@ public enum Quarter {
* @param quarters 所添加的季度数量
* @return 计算结果
*/
public Quarter plus(long quarters) {
final int amount = (int) ((quarters % 4) + 4);
public Quarter plus(int quarters) {
final int amount = (quarters % 4) + 4;
return Quarter.values()[(ordinal() + amount) % 4];
}
/**
* 减去指定数量的季度
* @param quarters 所减去的季度数量
* @return 计算结果
*/
public Quarter minus(long quarters) {
return plus(-(quarters % 4));
}
// computes end
// Getters

View File

@ -1,7 +1,5 @@
package cn.hutool.core.date;
import static java.time.temporal.ChronoField.YEAR;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.YearMonth;
@ -10,21 +8,32 @@ import java.util.Calendar;
import java.util.Date;
import java.util.Objects;
import static java.time.temporal.ChronoField.YEAR;
/**
* 表示年份与季度
*
* @author ZhouXY
* @since 5.8.37
*/
public final class YearQuarter implements Comparable<YearQuarter>, Serializable {
private static final long serialVersionUID = 3804145964419489753L;
/** 年份 */
/**
* 年份
*/
private final int year;
/** 季度 */
/**
* 季度
*/
private final Quarter quarter;
/** 季度开始日期 */
/**
* 季度开始日期
*/
private final LocalDate firstDate;
/** 季度结束日期 */
/**
* 季度结束日期
*/
private final LocalDate lastDate;
private YearQuarter(int year, Quarter quarter) {
@ -37,34 +46,34 @@ public final class YearQuarter implements Comparable<YearQuarter>, Serializable
// #region - StaticFactory
/**
* 根据指定年份与季度创建 {@link YearQuarter} 实例
* 根据指定年份与季度创建 {@code YearQuarter} 实例
*
* @param year 年份
* @param year 年份
* @param quarter 季度
* @return {@link YearQuarter} 实例
* @return {@code YearQuarter} 实例
*/
public static YearQuarter of(int year, int quarter) {
int yearValue = YEAR.checkValidIntValue(year);
int quarterValue = Quarter.checkValidIntValue(quarter);
return new YearQuarter(yearValue, Quarter.of(quarterValue));
return new YearQuarter(yearValue, Objects.requireNonNull(Quarter.of(quarterValue)));
}
/**
* 根据指定年份与季度创建 {@link YearQuarter} 实例
* 根据指定年份与季度创建 {@code YearQuarter} 实例
*
* @param year 年份
* @param year 年份
* @param quarter 季度
* @return {@link YearQuarter} 实例
* @return {@code YearQuarter} 实例
*/
public static YearQuarter of(int year, Quarter quarter) {
return new YearQuarter(YEAR.checkValidIntValue(year), Objects.requireNonNull(quarter));
}
/**
* 根据指定日期判断日期所在的年份与季度创建 {@link YearQuarter} 实例
* 根据指定日期判断日期所在的年份与季度创建 {@code YearQuarter} 实例
*
* @param date 日期
* @return {@link YearQuarter} 实例
* @return {@code YearQuarter} 实例
*/
public static YearQuarter of(LocalDate date) {
Objects.requireNonNull(date);
@ -72,25 +81,23 @@ public final class YearQuarter implements Comparable<YearQuarter>, Serializable
}
/**
* 根据指定日期判断日期所在的年份与季度创建 {@link YearQuarter} 实例
* 根据指定日期判断日期所在的年份与季度创建 {@code YearQuarter} 实例
*
* @param date 日期
* @return {@link YearQuarter} 实例
* @return {@code YearQuarter} 实例
*/
public static YearQuarter of(Date date) {
Objects.requireNonNull(date);
@SuppressWarnings("deprecation")
final int yearValue = YEAR.checkValidIntValue(date.getYear() + 1900L);
@SuppressWarnings("deprecation")
final int monthValue = date.getMonth() + 1;
@SuppressWarnings("deprecation") final int yearValue = YEAR.checkValidIntValue(date.getYear() + 1900L);
@SuppressWarnings("deprecation") final int monthValue = date.getMonth() + 1;
return new YearQuarter(yearValue, Quarter.fromMonth(monthValue));
}
/**
* 根据指定日期判断日期所在的年份与季度创建 {@link YearQuarter} 实例
* 根据指定日期判断日期所在的年份与季度创建 {@code YearQuarter} 实例
*
* @param date 日期
* @return {@link YearQuarter} 实例
* @return {@code YearQuarter} 实例
*/
public static YearQuarter of(Calendar date) {
Objects.requireNonNull(date);
@ -100,10 +107,10 @@ public final class YearQuarter implements Comparable<YearQuarter>, Serializable
}
/**
* 根据指定年月判断其所在的年份与季度创建 {@link YearQuarter} 实例
* 根据指定年月判断其所在的年份与季度创建 {@code YearQuarter} 实例
*
* @param yearMonth 年月
* @return {@link YearQuarter} 实例
* @return {@code YearQuarter} 实例
*/
public static YearQuarter of(YearMonth yearMonth) {
Objects.requireNonNull(yearMonth);
@ -126,6 +133,7 @@ public final class YearQuarter implements Comparable<YearQuarter>, Serializable
/**
* 年份
*
* @return 年份
*/
public int getYear() {
@ -134,6 +142,7 @@ public final class YearQuarter implements Comparable<YearQuarter>, Serializable
/**
* 季度
*
* @return 季度
*/
public Quarter getQuarter() {
@ -142,6 +151,7 @@ public final class YearQuarter implements Comparable<YearQuarter>, Serializable
/**
* 季度值 1 开始
*
* @return 季度值
*/
public int getQuarterValue() {
@ -150,6 +160,7 @@ public final class YearQuarter implements Comparable<YearQuarter>, Serializable
/**
* 该季度第一个月
*
* @return {@link YearMonth} 对象
*/
public YearMonth firstYearMonth() {
@ -158,6 +169,7 @@ public final class YearQuarter implements Comparable<YearQuarter>, Serializable
/**
* 该季度第一个月
*
* @return {@link Month} 对象
*/
public Month firstMonth() {
@ -166,6 +178,7 @@ public final class YearQuarter implements Comparable<YearQuarter>, Serializable
/**
* 该季度的第一个月
*
* @return 结果月份值从 1 开始1 表示 1月以此类推
*/
public int firstMonthValue() {
@ -174,6 +187,7 @@ public final class YearQuarter implements Comparable<YearQuarter>, Serializable
/**
* 该季度的最后一个月
*
* @return {@link YearMonth} 对象
*/
public YearMonth lastYearMonth() {
@ -182,6 +196,7 @@ public final class YearQuarter implements Comparable<YearQuarter>, Serializable
/**
* 该季度的最后一个月
*
* @return {@link Month} 对象
*/
public Month lastMonth() {
@ -190,6 +205,7 @@ public final class YearQuarter implements Comparable<YearQuarter>, Serializable
/**
* 该季度的最后一个月
*
* @return 结果月份值从 1 开始1 表示 1月以此类推
*/
public int lastMonthValue() {
@ -198,6 +214,7 @@ public final class YearQuarter implements Comparable<YearQuarter>, Serializable
/**
* 该季度的第一天
*
* @return {@link LocalDate} 对象
*/
public LocalDate firstDate() {
@ -206,6 +223,7 @@ public final class YearQuarter implements Comparable<YearQuarter>, Serializable
/**
* 该季度的最后一天
*
* @return {@link LocalDate} 对象
*/
public LocalDate lastDate() {
@ -218,6 +236,7 @@ public final class YearQuarter implements Comparable<YearQuarter>, Serializable
/**
* 添加季度
*
* @param quartersToAdd 要添加的季度数
* @return 计算结果
*/
@ -229,11 +248,12 @@ public final class YearQuarter implements Comparable<YearQuarter>, Serializable
long calcQuarters = quarterCount + quartersToAdd; // safe overflow
int newYear = YEAR.checkValidIntValue(Math.floorDiv(calcQuarters, 4));
int newQuarter = (int) Math.floorMod(calcQuarters, 4) + 1;
return new YearQuarter(newYear, Quarter.of(newQuarter));
return new YearQuarter(newYear, Objects.requireNonNull(Quarter.of(newQuarter)));
}
/**
* 减去季度
*
* @param quartersToMinus 要减去的季度数
* @return 计算结果
*/
@ -243,6 +263,7 @@ public final class YearQuarter implements Comparable<YearQuarter>, Serializable
/**
* 下一个季度
*
* @return 结果
*/
public YearQuarter nextQuarter() {
@ -251,6 +272,7 @@ public final class YearQuarter implements Comparable<YearQuarter>, Serializable
/**
* 上一个季度
*
* @return 结果
*/
public YearQuarter lastQuarter() {
@ -259,6 +281,7 @@ public final class YearQuarter implements Comparable<YearQuarter>, Serializable
/**
* 添加年份
*
* @param yearsToAdd 要添加的年份数
* @return 计算结果
*/
@ -272,6 +295,7 @@ public final class YearQuarter implements Comparable<YearQuarter>, Serializable
/**
* 减去年份
*
* @param yearsToMinus 要减去的年份数
* @return 计算结果
*/
@ -281,6 +305,7 @@ public final class YearQuarter implements Comparable<YearQuarter>, Serializable
/**
* 下一年同季度
*
* @return 计算结果
*/
public YearQuarter nextYear() {
@ -289,6 +314,7 @@ public final class YearQuarter implements Comparable<YearQuarter>, Serializable
/**
* 上一年同季度
*
* @return 计算结果
*/
public YearQuarter lastYear() {
@ -331,6 +357,7 @@ public final class YearQuarter implements Comparable<YearQuarter>, Serializable
/**
* 判断是否在指定年份季度之前
*
* @param other 比较对象
* @return 结果
*/
@ -340,6 +367,7 @@ public final class YearQuarter implements Comparable<YearQuarter>, Serializable
/**
* 判断是否在指定年份季度之后
*
* @param other 比较对象
* @return 结果
*/
@ -352,9 +380,9 @@ public final class YearQuarter implements Comparable<YearQuarter>, Serializable
// #region - toString
/**
* 返回 {@link YearQuarter} 的字符串表示形式 "2024 Q3"
* 返回 {@code YearQuarter} 的字符串表示形式 "2024 Q3"
*
* @return {@link YearQuarter} 的字符串表示形式
* @return {@code YearQuarter} 的字符串表示形式
*/
@Override
public String toString() {

View File

@ -1,13 +1,10 @@
package cn.hutool.core.date;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.Test;
import java.time.MonthDay;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class QuarterTest {
@ -209,60 +206,4 @@ public class QuarterTest {
assertEquals(Quarter.Q1, Quarter.Q4.plus(i));
}
}
@Test
void testMinusZeroAndNegativeNumber() {
for (int i = 0; i < 100; i += 4) {
assertEquals(Quarter.Q1, Quarter.Q1.minus(i));
assertEquals(Quarter.Q2, Quarter.Q2.minus(i));
assertEquals(Quarter.Q3, Quarter.Q3.minus(i));
assertEquals(Quarter.Q4, Quarter.Q4.minus(i));
}
for (int i = 1; i < 100 + 1; i += 4) {
assertEquals(Quarter.Q4, Quarter.Q1.minus(i));
assertEquals(Quarter.Q1, Quarter.Q2.minus(i));
assertEquals(Quarter.Q2, Quarter.Q3.minus(i));
assertEquals(Quarter.Q3, Quarter.Q4.minus(i));
}
for (int i = 2; i < 100 + 2; i += 4) {
assertEquals(Quarter.Q3, Quarter.Q1.minus(i));
assertEquals(Quarter.Q4, Quarter.Q2.minus(i));
assertEquals(Quarter.Q1, Quarter.Q3.minus(i));
assertEquals(Quarter.Q2, Quarter.Q4.minus(i));
}
for (int i = 3; i < 100 + 3; i += 4) {
assertEquals(Quarter.Q2, Quarter.Q1.minus(i));
assertEquals(Quarter.Q3, Quarter.Q2.minus(i));
assertEquals(Quarter.Q4, Quarter.Q3.minus(i));
assertEquals(Quarter.Q1, Quarter.Q4.minus(i));
}
}
@Test
void testMinusZeroAndPositiveRealNumbers() {
for (int i = 0; i > -100; i -= 4) {
assertEquals(Quarter.Q1, Quarter.Q1.minus(i));
assertEquals(Quarter.Q2, Quarter.Q2.minus(i));
assertEquals(Quarter.Q3, Quarter.Q3.minus(i));
assertEquals(Quarter.Q4, Quarter.Q4.minus(i));
}
for (int i = -1; i > -(100 + 1); i -= 4) {
assertEquals(Quarter.Q2, Quarter.Q1.minus(i));
assertEquals(Quarter.Q3, Quarter.Q2.minus(i));
assertEquals(Quarter.Q4, Quarter.Q3.minus(i));
assertEquals(Quarter.Q1, Quarter.Q4.minus(i));
}
for (int i = -2; i > -(100 + 2); i -= 4) {
assertEquals(Quarter.Q3, Quarter.Q1.minus(i));
assertEquals(Quarter.Q4, Quarter.Q2.minus(i));
assertEquals(Quarter.Q1, Quarter.Q3.minus(i));
assertEquals(Quarter.Q2, Quarter.Q4.minus(i));
}
for (int i = -3; i > -(100 + 3); i -= 4) {
assertEquals(Quarter.Q4, Quarter.Q1.minus(i));
assertEquals(Quarter.Q1, Quarter.Q2.minus(i));
assertEquals(Quarter.Q2, Quarter.Q3.minus(i));
assertEquals(Quarter.Q3, Quarter.Q4.minus(i));
}
}
}