From 1113389cdb63363ba45c856954f06f311ff80a5a Mon Sep 17 00:00:00 2001 From: ZhouXY108 Date: Thu, 26 Dec 2024 18:33:00 +0800 Subject: [PATCH] commit. --- ProgressOfTesting.txt | 8 +- .../zhouxy/plusone/commons/time/Quarter.java | 4 +- .../plusone/commons/time/YearQuarter.java | 57 +- .../plusone/commons/util/IdGenerator.java | 3 +- .../zhouxy/plusone/commons/util/IdWorker.java | 1 + .../commons/util/SnowflakeIdGenerator.java | 3 - .../commons/time/YearQuarterTests.java | 842 +++++++++++++++++- 7 files changed, 842 insertions(+), 76 deletions(-) diff --git a/ProgressOfTesting.txt b/ProgressOfTesting.txt index 2f81ee2..f1008be 100644 --- a/ProgressOfTesting.txt +++ b/ProgressOfTesting.txt @@ -80,7 +80,7 @@ xyz.zhouxy.plusone.commons │ ├───time │ Quarter.java [Y] - │ YearQuarter.java [-] + │ YearQuarter.java [-]* │ └───util ArrayTools.java [-] @@ -90,12 +90,12 @@ xyz.zhouxy.plusone.commons DateTimeTools.java [-] Enumeration.java [Y] EnumTools.java [Y] - IdGenerator.java [ ] - IdWorker.java [ ] + IdGenerator.java [ ]* + IdWorker.java [ ]* Numbers.java [Y] OptionalTools.java [Y] RandomTools.java [ ] RegexTools.java [ ] - SnowflakeIdGenerator.java [ ] + SnowflakeIdGenerator.java [ ]* StringTools.java [Y] TreeBuilder.java [Y] diff --git a/src/main/java/xyz/zhouxy/plusone/commons/time/Quarter.java b/src/main/java/xyz/zhouxy/plusone/commons/time/Quarter.java index 71efd48..279ca23 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/time/Quarter.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/time/Quarter.java @@ -16,6 +16,7 @@ package xyz.zhouxy.plusone.commons.time; +import java.time.DateTimeException; import java.time.Month; import java.time.MonthDay; import java.time.temporal.ChronoField; @@ -171,7 +172,8 @@ public enum Quarter implements IWithIntCode { // Getters end public static int checkValidIntValue(int value) { - AssertTools.checkArgument(value >= 1 && value <= 4, () -> "Invalid value for Quarter: " + value); + AssertTools.checkCondition(value >= 1 && value <= 4, + () -> new DateTimeException("Invalid value for Quarter: " + value)); return value; } diff --git a/src/main/java/xyz/zhouxy/plusone/commons/time/YearQuarter.java b/src/main/java/xyz/zhouxy/plusone/commons/time/YearQuarter.java index 7fd4885..b03d82d 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/time/YearQuarter.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/time/YearQuarter.java @@ -22,6 +22,7 @@ import java.io.Serializable; import java.time.LocalDate; import java.time.Month; import java.time.YearMonth; +import java.time.temporal.ChronoField; import java.util.Calendar; import java.util.Date; import java.util.Objects; @@ -52,7 +53,6 @@ public final class YearQuarter implements Comparable, Serializable private final LocalDate lastDate; private YearQuarter(int year, @Nonnull Quarter quarter) { - AssertTools.checkNotNull(quarter, "Quarter can not be null."); this.year = year; this.quarter = quarter; this.firstDate = quarter.firstMonthDay().atYear(year); @@ -70,7 +70,7 @@ public final class YearQuarter implements Comparable, Serializable */ @StaticFactoryMethod(YearQuarter.class) public static YearQuarter of(int year, int quarter) { - return of(year, Quarter.of(quarter)); + return new YearQuarter(YEAR.checkValidIntValue(year), Quarter.of(quarter)); } /** @@ -81,8 +81,8 @@ public final class YearQuarter implements Comparable, Serializable * @return {@link YearQuarter} 实例 */ @StaticFactoryMethod(YearQuarter.class) - public static YearQuarter of(int year, @Nonnull Quarter quarter) { - return new YearQuarter(year, quarter); + public static YearQuarter of(int year, Quarter quarter) { + return new YearQuarter(YEAR.checkValidIntValue(year), Objects.requireNonNull(quarter)); } /** @@ -92,8 +92,9 @@ public final class YearQuarter implements Comparable, Serializable * @return {@link YearQuarter} 实例 */ @StaticFactoryMethod(YearQuarter.class) - public static YearQuarter of(@Nonnull LocalDate date) { - return of(date.getYear(), Quarter.fromMonth(date.getMonth())); + public static YearQuarter of(LocalDate date) { + AssertTools.checkNotNull(date); + return new YearQuarter(date.getYear(), Quarter.fromMonth(date.getMonth())); } /** @@ -103,12 +104,13 @@ public final class YearQuarter implements Comparable, Serializable * @return {@link YearQuarter} 实例 */ @StaticFactoryMethod(YearQuarter.class) - public static YearQuarter of(@Nonnull Date date) { + public static YearQuarter of(Date date) { + AssertTools.checkNotNull(date); @SuppressWarnings("deprecation") - final int year = date.getYear() + 1900; + final int yearValue = YEAR.checkValidIntValue(date.getYear() + 1900L); @SuppressWarnings("deprecation") - final int month = date.getMonth() + 1; - return of(year, Quarter.fromMonth(month)); + final int monthValue = date.getMonth() + 1; + return new YearQuarter(yearValue, Quarter.fromMonth(monthValue)); } /** @@ -119,7 +121,10 @@ public final class YearQuarter implements Comparable, Serializable */ @StaticFactoryMethod(YearQuarter.class) public static YearQuarter of(Calendar date) { - return of(date.get(Calendar.YEAR), Quarter.fromMonth(date.get(Calendar.MONTH) + 1)); + AssertTools.checkNotNull(date); + final int yearValue = ChronoField.YEAR.checkValidIntValue(date.get(Calendar.YEAR)); + final int monthValue = date.get(Calendar.MONTH) + 1; + return new YearQuarter(yearValue, Quarter.fromMonth(monthValue)); } /** @@ -130,9 +135,15 @@ public final class YearQuarter implements Comparable, Serializable */ @StaticFactoryMethod(YearQuarter.class) public static YearQuarter of(YearMonth yearMonth) { + AssertTools.checkNotNull(yearMonth); return of(yearMonth.getYear(), Quarter.fromMonth(yearMonth.getMonth())); } + @StaticFactoryMethod(YearQuarter.class) + public static YearQuarter now() { + return of(LocalDate.now()); + } + // #endregion // #region - Getters @@ -153,11 +164,11 @@ public final class YearQuarter implements Comparable, Serializable return YearMonth.of(this.year, this.quarter.firstMonth()); } - public Month firstMonth() { + public Month firstMonth() { // TODO 单元测试 return this.quarter.firstMonth(); } - public int firstMonthValue() { + public int firstMonthValue() { // TODO 单元测试 return this.quarter.firstMonthValue(); } @@ -165,11 +176,11 @@ public final class YearQuarter implements Comparable, Serializable return YearMonth.of(this.year, this.quarter.lastMonth()); } - public Month lastMonth() { + public Month lastMonth() { // TODO 单元测试 return this.quarter.lastMonth(); } - public int lastMonthValue() { + public int lastMonthValue() { // TODO 单元测试 return this.quarter.lastMonthValue(); } @@ -193,7 +204,7 @@ public final class YearQuarter implements Comparable, Serializable long calcQuarters = quarterCount + quartersToAdd; // safe overflow int newYear = YEAR.checkValidIntValue(Math.floorDiv(calcQuarters, 4)); int newQuarter = (int) Math.floorMod(calcQuarters, 4) + 1; - return of(newYear, Quarter.of(newQuarter)); + return new YearQuarter(newYear, Quarter.of(newQuarter)); } public YearQuarter minusQuarters(long quartersToAdd) { // TODO 单元测试 @@ -213,18 +224,18 @@ public final class YearQuarter implements Comparable, Serializable return this; } int newYear = YEAR.checkValidIntValue(this.year + yearsToAdd); // safe overflow - return of(newYear, this.quarter); + return new YearQuarter(newYear, this.quarter); } - public YearQuarter minusYears(long yearsToAdd) { + public YearQuarter minusYears(long yearsToAdd) { // TODO 单元测试 return plusYears(-yearsToAdd); } - public YearQuarter nextYear() { + public YearQuarter nextYear() { // TODO 单元测试 return plusYears(1L); } - public YearQuarter lastYear() { + public YearQuarter lastYear() { // TODO 单元测试 return minusYears(1L); } @@ -238,7 +249,7 @@ public final class YearQuarter implements Comparable, Serializable } @Override - public boolean equals(Object obj) { + public boolean equals(Object obj) { // TODO 单元测试 if (this == obj) return true; if (obj == null) @@ -262,11 +273,11 @@ public final class YearQuarter implements Comparable, Serializable return cmp; } - public boolean isBefore(YearQuarter other) { + public boolean isBefore(YearQuarter other) { // TODO 单元测试 return this.compareTo(other) < 0; } - public boolean isAfter(YearQuarter other) { + public boolean isAfter(YearQuarter other) { // TODO 单元测试 return this.compareTo(other) > 0; } diff --git a/src/main/java/xyz/zhouxy/plusone/commons/util/IdGenerator.java b/src/main/java/xyz/zhouxy/plusone/commons/util/IdGenerator.java index 66051a9..e775dbd 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/util/IdGenerator.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/util/IdGenerator.java @@ -21,9 +21,8 @@ import java.util.Objects; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; -import com.google.common.annotations.Beta; +// TODO [添加] javadoc -@Beta public class IdGenerator { // ===== UUID ===== diff --git a/src/main/java/xyz/zhouxy/plusone/commons/util/IdWorker.java b/src/main/java/xyz/zhouxy/plusone/commons/util/IdWorker.java index e806cb2..b2fee31 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/util/IdWorker.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/util/IdWorker.java @@ -24,6 +24,7 @@ import java.util.concurrent.atomic.AtomicLong; import xyz.zhouxy.plusone.commons.exception.system.NoAvailableMacFoundException; +// TODO [添加] javadoc public class IdWorker { diff --git a/src/main/java/xyz/zhouxy/plusone/commons/util/SnowflakeIdGenerator.java b/src/main/java/xyz/zhouxy/plusone/commons/util/SnowflakeIdGenerator.java index c89a4bc..86845a9 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/util/SnowflakeIdGenerator.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/util/SnowflakeIdGenerator.java @@ -18,12 +18,9 @@ package xyz.zhouxy.plusone.commons.util; import java.util.concurrent.TimeUnit; -import com.google.common.annotations.Beta; - /** * Twitter_Snowflake */ -@Beta public class SnowflakeIdGenerator { // ==============================Fields=========================================== diff --git a/src/test/java/xyz/zhouxy/plusone/commons/time/YearQuarterTests.java b/src/test/java/xyz/zhouxy/plusone/commons/time/YearQuarterTests.java index 0e63de8..94bbc31 100644 --- a/src/test/java/xyz/zhouxy/plusone/commons/time/YearQuarterTests.java +++ b/src/test/java/xyz/zhouxy/plusone/commons/time/YearQuarterTests.java @@ -21,66 +21,801 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; import lombok.extern.slf4j.Slf4j; +import xyz.zhouxy.plusone.commons.util.DateTimeTools; + +import java.text.SimpleDateFormat; +import java.time.DateTimeException; +import java.time.Instant; import java.time.LocalDate; +import java.time.Year; import java.time.YearMonth; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; +import java.util.stream.IntStream; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @Slf4j public class YearQuarterTests { - @Test - void of_ValidYearAndQuarter_CreatesYearQuarter() { - int year = 2023; - Quarter quarter = Quarter.Q1; + // ================================ + // #region - of(int year, int quarter) + // ================================ - YearQuarter expected = YearQuarter.of(year, quarter); - YearQuarter actual = YearQuarter.of(LocalDate.of(year, 2, 28)); + @ParameterizedTest + @ValueSource(ints = { 1, 2, 3, 4 }) + void of_ValidYearAndQuarterValue_CreatesYearQuarter(int quarter) { + { + int year = 2024; + YearQuarter yearQuarter = YearQuarter.of(year, quarter); + log.info("{}", yearQuarter); + assertEquals(year, yearQuarter.getYear()); + assertEquals(Quarter.of(quarter), yearQuarter.getQuarter()); + assertEquals(quarter, yearQuarter.getQuarterValue()); + } + { + int year = Year.MIN_VALUE; + YearQuarter yearQuarter = YearQuarter.of(year, quarter); + assertEquals(year, yearQuarter.getYear()); + assertEquals(Quarter.of(quarter), yearQuarter.getQuarter()); + assertEquals(quarter, yearQuarter.getQuarterValue()); + } + { + int year = Year.MAX_VALUE; + YearQuarter yearQuarter = YearQuarter.of(year, quarter); + assertEquals(year, yearQuarter.getYear()); + assertEquals(Quarter.of(quarter), yearQuarter.getQuarter()); + assertEquals(quarter, yearQuarter.getQuarterValue()); + } + } - assertEquals(expected, actual); + @ParameterizedTest + @ValueSource(ints = { -1, 0, 5, 108 }) + void of_ValidYearAndInvalidQuarterValue_DateTimeException(int quarter) { + int year = 2024; + assertThrows(DateTimeException.class, () -> { + YearQuarter.of(year, quarter); + }); + } - assertEquals("2023 Q1", actual.toString()); + @ParameterizedTest + @ValueSource(ints = { Year.MIN_VALUE - 1, Year.MAX_VALUE + 1 }) + void of_InvalidYearAndValidQuarterValue_DateTimeException(int year) { + assertThrows(DateTimeException.class, () -> { + YearQuarter.of(year, 1); + }); + assertThrows(DateTimeException.class, () -> { + YearQuarter.of(year, 2); + }); + assertThrows(DateTimeException.class, () -> { + YearQuarter.of(year, 3); + }); + assertThrows(DateTimeException.class, () -> { + YearQuarter.of(year, 4); + }); } @Test - @SuppressWarnings("null") - void of_InvalidQuarter_ThrowsNullPointerException() { - int year = 2023; - Quarter quarter = null; - - assertThrows(NullPointerException.class, () -> YearQuarter.of(year, quarter)); - } - - @Test - void of_ValidYearQuarter_GetsCorrectStartAndEndDate() { - - for (int year = 1990; year <= 2024; year++) { - for (int quarterValue = 1; quarterValue <= 4; quarterValue++) { - Quarter quarter = Quarter.of(quarterValue); - YearQuarter yearQuarter = YearQuarter.of(year, quarter); - - LocalDate expectedStartDate = quarter.firstMonthDay().atYear(year); - log.info("{} - expectedStartDate: {}", yearQuarter, expectedStartDate); - LocalDate expectedEndDate = quarter.lastMonthDay().atYear(year); - log.info("{} - expectedEndDate: {}", yearQuarter, expectedEndDate); - - assertEquals(expectedStartDate, yearQuarter.firstDate()); - assertEquals(expectedEndDate, yearQuarter.lastDate()); + void of_InvalidYearAndInvalidQuarterValue_DateTimeException() { + final int[] years = { Year.MIN_VALUE - 1, Year.MAX_VALUE + 1 }; + final int[] quarters = { -1, 0, 5, 108 }; + for (int year : years) { + final int yearValue = year; + for (int quarter : quarters) { + final int quarterValue = quarter; + assertThrows(DateTimeException.class, + () -> YearQuarter.of(yearValue, quarterValue)); } } } + // ================================ + // #endregion - of(int year, int quarter) + // ================================ + + // ================================ + // #region - of(int year, Quarter quarter) + // ================================ + + @ParameterizedTest + @ValueSource(ints = { 1, 2, 3, 4 }) + void of_ValidYearAndQuarter_CreatesYearQuarter(int quarterValue) { + { + int year = 2024; + Quarter quarter = Quarter.of(quarterValue); + YearQuarter yearQuarter = YearQuarter.of(year, quarter); + log.info("{}", yearQuarter); + assertEquals(year, yearQuarter.getYear()); + assertEquals(quarter, yearQuarter.getQuarter()); + assertEquals(quarterValue, yearQuarter.getQuarterValue()); + } + { + int year = Year.MIN_VALUE; + Quarter quarter = Quarter.of(quarterValue); + YearQuarter yearQuarter = YearQuarter.of(year, quarter); + assertEquals(year, yearQuarter.getYear()); + assertEquals(quarter, yearQuarter.getQuarter()); + assertEquals(quarterValue, yearQuarter.getQuarterValue()); + } + { + int year = Year.MAX_VALUE; + Quarter quarter = Quarter.of(quarterValue); + YearQuarter yearQuarter = YearQuarter.of(year, quarter); + assertEquals(year, yearQuarter.getYear()); + assertEquals(quarter, yearQuarter.getQuarter()); + assertEquals(quarterValue, yearQuarter.getQuarterValue()); + } + } + + @Test + void of_ValidYearAndNullQuarter_NullPointerException() { + int year = 2024; + assertThrows(NullPointerException.class, () -> { + YearQuarter.of(year, null); + }); + } + + @ParameterizedTest + @ValueSource(ints = { Year.MIN_VALUE - 1, Year.MAX_VALUE + 1 }) + void of_InvalidYearAndValidQuarter_DateTimeException(int year) { + assertThrows(DateTimeException.class, () -> { + YearQuarter.of(year, Quarter.Q1); + }); + assertThrows(DateTimeException.class, () -> { + YearQuarter.of(year, Quarter.Q2); + }); + assertThrows(DateTimeException.class, () -> { + YearQuarter.of(year, Quarter.Q3); + }); + assertThrows(DateTimeException.class, () -> { + YearQuarter.of(year, Quarter.Q4); + }); + } + + @Test + void of_InvalidYearAndNullQuarter_DateTimeException() { + final int[] years = { Year.MIN_VALUE - 1, Year.MAX_VALUE + 1 }; + for (int year : years) { + final int yearValue = year; + assertThrows(DateTimeException.class, + () -> YearQuarter.of(yearValue, null)); + + } + } + + // ================================ + // #endregion - of(int year, Quarter quarter) + // ================================ + + // ================================ + // #region - of(LocalDate date) + // ================================ + + @ParameterizedTest + @ValueSource(ints = { + 2023, // 非闰年 + 2024, // 闰年 + Year.MIN_VALUE, + Year.MAX_VALUE, + }) + void of_ValidLocalDate_CreatesYearQuarter_Q1(int year) { + { + LocalDate date = YearMonth.of(year, 1).atDay(1); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(1, yq.getQuarterValue()); + assertSame(Quarter.Q1, yq.getQuarter()); + } + { + LocalDate date = YearMonth.of(year, 1).atEndOfMonth(); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(1, yq.getQuarterValue()); + assertSame(Quarter.Q1, yq.getQuarter()); + } + { + LocalDate date = YearMonth.of(year, 2).atDay(1); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(1, yq.getQuarterValue()); + assertSame(Quarter.Q1, yq.getQuarter()); + } + { + LocalDate date = YearMonth.of(year, 2).atEndOfMonth(); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(1, yq.getQuarterValue()); + assertSame(Quarter.Q1, yq.getQuarter()); + } + { + LocalDate date = YearMonth.of(year, 3).atDay(1); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(1, yq.getQuarterValue()); + assertSame(Quarter.Q1, yq.getQuarter()); + } + { + LocalDate date = YearMonth.of(year, 3).atEndOfMonth(); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(1, yq.getQuarterValue()); + assertSame(Quarter.Q1, yq.getQuarter()); + } + } + @ParameterizedTest @ValueSource(ints = { - 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, - 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, - 2020, 2021, 2022, 2023, 2024 + 2023, // 非闰年 + 2024, // 闰年 + Year.MIN_VALUE, + Year.MAX_VALUE, }) - void testFirstYearMonth(int year) { + void of_ValidLocalDate_CreatesYearQuarter_Q2(int year) { + { + LocalDate date = YearMonth.of(year, 4).atDay(1); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(2, yq.getQuarterValue()); + assertSame(Quarter.Q2, yq.getQuarter()); + } + { + LocalDate date = YearMonth.of(year, 4).atEndOfMonth(); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(2, yq.getQuarterValue()); + assertSame(Quarter.Q2, yq.getQuarter()); + } + { + LocalDate date = YearMonth.of(year, 5).atDay(1); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(2, yq.getQuarterValue()); + assertSame(Quarter.Q2, yq.getQuarter()); + } + { + LocalDate date = YearMonth.of(year, 5).atEndOfMonth(); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(2, yq.getQuarterValue()); + assertSame(Quarter.Q2, yq.getQuarter()); + } + { + LocalDate date = YearMonth.of(year, 6).atDay(1); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(2, yq.getQuarterValue()); + assertSame(Quarter.Q2, yq.getQuarter()); + } + { + LocalDate date = YearMonth.of(year, 6).atEndOfMonth(); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(2, yq.getQuarterValue()); + assertSame(Quarter.Q2, yq.getQuarter()); + } + } + + @ParameterizedTest + @ValueSource(ints = { + 2023, // 非闰年 + 2024, // 闰年 + Year.MIN_VALUE, + Year.MAX_VALUE, + }) + void of_ValidLocalDate_CreatesYearQuarter_Q3(int year) { + { + LocalDate date = YearMonth.of(year, 7).atDay(1); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(3, yq.getQuarterValue()); + assertSame(Quarter.Q3, yq.getQuarter()); + } + { + LocalDate date = YearMonth.of(year, 7).atEndOfMonth(); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(3, yq.getQuarterValue()); + assertSame(Quarter.Q3, yq.getQuarter()); + } + { + LocalDate date = YearMonth.of(year, 8).atDay(1); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(3, yq.getQuarterValue()); + assertSame(Quarter.Q3, yq.getQuarter()); + } + { + LocalDate date = YearMonth.of(year, 8).atEndOfMonth(); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(3, yq.getQuarterValue()); + assertSame(Quarter.Q3, yq.getQuarter()); + } + { + LocalDate date = YearMonth.of(year, 9).atDay(1); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(3, yq.getQuarterValue()); + assertSame(Quarter.Q3, yq.getQuarter()); + } + { + LocalDate date = YearMonth.of(year, 9).atEndOfMonth(); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(3, yq.getQuarterValue()); + assertSame(Quarter.Q3, yq.getQuarter()); + } + } + + @ParameterizedTest + @ValueSource(ints = { + 2023, // 非闰年 + 2024, // 闰年 + Year.MIN_VALUE, + Year.MAX_VALUE, + }) + void of_ValidLocalDate_CreatesYearQuarter_Q4(int year) { + { + LocalDate date = YearMonth.of(year, 10).atDay(1); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(4, yq.getQuarterValue()); + assertSame(Quarter.Q4, yq.getQuarter()); + } + { + LocalDate date = YearMonth.of(year, 10).atEndOfMonth(); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(4, yq.getQuarterValue()); + assertSame(Quarter.Q4, yq.getQuarter()); + } + { + LocalDate date = YearMonth.of(year, 11).atDay(1); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(4, yq.getQuarterValue()); + assertSame(Quarter.Q4, yq.getQuarter()); + } + { + LocalDate date = YearMonth.of(year, 11).atEndOfMonth(); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(4, yq.getQuarterValue()); + assertSame(Quarter.Q4, yq.getQuarter()); + } + { + LocalDate date = YearMonth.of(year, 12).atDay(1); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(4, yq.getQuarterValue()); + assertSame(Quarter.Q4, yq.getQuarter()); + } + { + LocalDate date = YearMonth.of(year, 12).atEndOfMonth(); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(4, yq.getQuarterValue()); + assertSame(Quarter.Q4, yq.getQuarter()); + } + } + + @Test + void of_NullLocalDate_NullPointerException() { + LocalDate date = null; + assertThrows(NullPointerException.class, () -> { + YearQuarter.of(date); + }); + } + + // ================================ + // #endregion - of(LocalDate date) + // ================================ + + // ================================ + // #region - of(Date date) + // ================================ + + @SuppressWarnings("deprecation") + @ParameterizedTest + @ValueSource(ints = { + 2023, // 非闰年 + 2024, // 闰年 + 1, + 999999, + }) + void of_ValidDate_CreatesYearQuarter(int year) { + { + Date date = new Date(year - 1900, 1 - 1, 1); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(1, yq.getQuarterValue()); + assertSame(Quarter.Q1, yq.getQuarter()); + } + { + Date date = new Date(year - 1900, 3 - 1, 31, 23, 59, 59); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(1, yq.getQuarterValue()); + assertSame(Quarter.Q1, yq.getQuarter()); + } + { + Date date = new Date(year - 1900, 4 - 1, 1); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(2, yq.getQuarterValue()); + assertSame(Quarter.Q2, yq.getQuarter()); + } + { + Date date = new Date(year - 1900, 6 - 1, 30, 23, 59, 59); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(2, yq.getQuarterValue()); + assertSame(Quarter.Q2, yq.getQuarter()); + } + { + Date date = new Date(year - 1900, 7 - 1, 1); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(3, yq.getQuarterValue()); + assertSame(Quarter.Q3, yq.getQuarter()); + } + { + Date date = new Date(year - 1900, 9 - 1, 30, 23, 59, 59); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(3, yq.getQuarterValue()); + assertSame(Quarter.Q3, yq.getQuarter()); + } + { + Date date = new Date(year - 1900, 10 - 1, 1); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(4, yq.getQuarterValue()); + assertSame(Quarter.Q4, yq.getQuarter()); + } + { + Date date = new Date(year - 1900, 12 - 1, 31, 23, 59, 59); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(4, yq.getQuarterValue()); + assertSame(Quarter.Q4, yq.getQuarter()); + } + } + + @Test + void of_NullDate_NullPointerException() { + Date date = null; + assertThrows(NullPointerException.class, () -> { + YearQuarter.of(date); + }); + } + + // ================================ + // #endregion - of(Date date) + // ================================ + + // ================================ + // #region - of(Calendar date) + // ================================ + + @ParameterizedTest + @ValueSource(ints = { + 2023, // 非闰年 + 2024, // 闰年 + 1, + 999999, + }) + void of_ValidCalendar_CreatesYearQuarter(int year) { + Calendar date = Calendar.getInstance(); + { + date.set(year, 1 - 1, 1); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(1, yq.getQuarterValue()); + assertSame(Quarter.Q1, yq.getQuarter()); + } + { + date.set(year, 3 - 1, 31, 23, 59, 59); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(1, yq.getQuarterValue()); + assertSame(Quarter.Q1, yq.getQuarter()); + } + { + date.set(year, 4 - 1, 1); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(2, yq.getQuarterValue()); + assertSame(Quarter.Q2, yq.getQuarter()); + } + { + date.set(year, 6 - 1, 30, 23, 59, 59); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(2, yq.getQuarterValue()); + assertSame(Quarter.Q2, yq.getQuarter()); + } + { + date.set(year, 7 - 1, 1); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(3, yq.getQuarterValue()); + assertSame(Quarter.Q3, yq.getQuarter()); + } + { + date.set(year, 9 - 1, 30, 23, 59, 59); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(3, yq.getQuarterValue()); + assertSame(Quarter.Q3, yq.getQuarter()); + } + { + date.set(year, 10 - 1, 1); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(4, yq.getQuarterValue()); + assertSame(Quarter.Q4, yq.getQuarter()); + } + { + date.set(year, 12 - 1, 31, 23, 59, 59); + YearQuarter yq = YearQuarter.of(date); + assertEquals(year, yq.getYear()); + assertEquals(4, yq.getQuarterValue()); + assertSame(Quarter.Q4, yq.getQuarter()); + } + } + + @Test + void of_NullCalendar_NullPointerException() { + Calendar date = null; + assertThrows(NullPointerException.class, () -> { + YearQuarter.of(date); + }); + } + + // ================================ + // #endregion - of(Calendar date) + // ================================ + + // ================================ + // #region - of(YearMonth yearMonth) + // ================================ + + @ParameterizedTest + @ValueSource(ints = { + 2023, // 非闰年 + 2024, // 闰年 + Year.MIN_VALUE, + Year.MAX_VALUE, + }) + void of_ValidYearMonth_CreatesYearMnoth_Q1(int year) { + { + YearMonth yearMonth = YearMonth.of(year, 1); + YearQuarter yearQuarter = YearQuarter.of(yearMonth); + assertEquals(year, yearQuarter.getYear()); + assertEquals(1, yearQuarter.getQuarterValue()); + assertSame(Quarter.Q1, yearQuarter.getQuarter()); + } + { + YearMonth yearMonth = YearMonth.of(year, 2); + YearQuarter yearQuarter = YearQuarter.of(yearMonth); + assertEquals(year, yearQuarter.getYear()); + assertEquals(1, yearQuarter.getQuarterValue()); + assertSame(Quarter.Q1, yearQuarter.getQuarter()); + } + { + YearMonth yearMonth = YearMonth.of(year, 3); + YearQuarter yearQuarter = YearQuarter.of(yearMonth); + assertEquals(year, yearQuarter.getYear()); + assertEquals(1, yearQuarter.getQuarterValue()); + assertSame(Quarter.Q1, yearQuarter.getQuarter()); + } + } + + @ParameterizedTest + @ValueSource(ints = { + 2023, // 非闰年 + 2024, // 闰年 + Year.MIN_VALUE, + Year.MAX_VALUE, + }) + void of_ValidYearMonth_CreatesYearMnoth_Q2(int year) { + { + YearMonth yearMonth = YearMonth.of(year, 4); + YearQuarter yearQuarter = YearQuarter.of(yearMonth); + assertEquals(year, yearQuarter.getYear()); + assertEquals(2, yearQuarter.getQuarterValue()); + assertSame(Quarter.Q2, yearQuarter.getQuarter()); + } + { + YearMonth yearMonth = YearMonth.of(year, 5); + YearQuarter yearQuarter = YearQuarter.of(yearMonth); + assertEquals(year, yearQuarter.getYear()); + assertEquals(2, yearQuarter.getQuarterValue()); + assertSame(Quarter.Q2, yearQuarter.getQuarter()); + } + { + YearMonth yearMonth = YearMonth.of(year, 6); + YearQuarter yearQuarter = YearQuarter.of(yearMonth); + assertEquals(year, yearQuarter.getYear()); + assertEquals(2, yearQuarter.getQuarterValue()); + assertSame(Quarter.Q2, yearQuarter.getQuarter()); + } + } + + @ParameterizedTest + @ValueSource(ints = { + 2023, // 非闰年 + 2024, // 闰年 + Year.MIN_VALUE, + Year.MAX_VALUE, + }) + void of_ValidYearMonth_CreatesYearMnoth_Q3(int year) { + { + YearMonth yearMonth = YearMonth.of(year, 7); + YearQuarter yearQuarter = YearQuarter.of(yearMonth); + assertEquals(year, yearQuarter.getYear()); + assertEquals(3, yearQuarter.getQuarterValue()); + assertSame(Quarter.Q3, yearQuarter.getQuarter()); + } + { + YearMonth yearMonth = YearMonth.of(year, 8); + YearQuarter yearQuarter = YearQuarter.of(yearMonth); + assertEquals(year, yearQuarter.getYear()); + assertEquals(3, yearQuarter.getQuarterValue()); + assertSame(Quarter.Q3, yearQuarter.getQuarter()); + } + { + YearMonth yearMonth = YearMonth.of(year, 9); + YearQuarter yearQuarter = YearQuarter.of(yearMonth); + assertEquals(year, yearQuarter.getYear()); + assertEquals(3, yearQuarter.getQuarterValue()); + assertSame(Quarter.Q3, yearQuarter.getQuarter()); + } + } + + @ParameterizedTest + @ValueSource(ints = { + 2023, // 非闰年 + 2024, // 闰年 + Year.MIN_VALUE, + Year.MAX_VALUE, + }) + void of_ValidYearMonth_CreatesYearMnoth_Q4(int year) { + { + YearMonth yearMonth = YearMonth.of(year, 10); + YearQuarter yearQuarter = YearQuarter.of(yearMonth); + assertEquals(year, yearQuarter.getYear()); + assertEquals(4, yearQuarter.getQuarterValue()); + assertSame(Quarter.Q4, yearQuarter.getQuarter()); + } + { + YearMonth yearMonth = YearMonth.of(year, 11); + YearQuarter yearQuarter = YearQuarter.of(yearMonth); + assertEquals(year, yearQuarter.getYear()); + assertEquals(4, yearQuarter.getQuarterValue()); + assertSame(Quarter.Q4, yearQuarter.getQuarter()); + } + { + YearMonth yearMonth = YearMonth.of(year, 12); + YearQuarter yearQuarter = YearQuarter.of(yearMonth); + assertEquals(year, yearQuarter.getYear()); + assertEquals(4, yearQuarter.getQuarterValue()); + assertSame(Quarter.Q4, yearQuarter.getQuarter()); + } + } + + @ParameterizedTest + @ValueSource(ints = { + 2023, // 非闰年 + 2024, // 闰年 + Year.MIN_VALUE, + Year.MAX_VALUE, + }) + void of_NullYearMonth_CreatesYearMnoth_Q4(int year) { + { + YearMonth yearMonth = YearMonth.of(year, 10); + YearQuarter yearQuarter = YearQuarter.of(yearMonth); + assertEquals(year, yearQuarter.getYear()); + assertEquals(4, yearQuarter.getQuarterValue()); + assertSame(Quarter.Q4, yearQuarter.getQuarter()); + } + { + YearMonth yearMonth = YearMonth.of(year, 11); + YearQuarter yearQuarter = YearQuarter.of(yearMonth); + assertEquals(year, yearQuarter.getYear()); + assertEquals(4, yearQuarter.getQuarterValue()); + assertSame(Quarter.Q4, yearQuarter.getQuarter()); + } + { + YearMonth yearMonth = YearMonth.of(year, 12); + YearQuarter yearQuarter = YearQuarter.of(yearMonth); + assertEquals(year, yearQuarter.getYear()); + assertEquals(4, yearQuarter.getQuarterValue()); + assertSame(Quarter.Q4, yearQuarter.getQuarter()); + } + } + + // ================================ + // #endregion - of(YearMonth yearMonth) + // ================================ + + // ================================ + // #region - firstDate & lastDate + // ================================ + + @ParameterizedTest + @ValueSource(ints = { 1949, 1990, 2000, 2008, 2023, 2024, Year.MIN_VALUE, Year.MAX_VALUE }) + void test_getFirstDate_And_getLastDate(int year) { + { + final int quarterValue = 1; + YearQuarter yearQuarter = YearQuarter.of(year, quarterValue); + + LocalDate expectedFirstDate = LocalDate.of(year, 1, 1); + log.info("{} - expectedFirstDate: {}", yearQuarter, expectedFirstDate); + LocalDate expectedLastDate = LocalDate.of(year, 3, 31); + log.info("{} - expectedLastDate: {}", yearQuarter, expectedLastDate); + + assertEquals(expectedFirstDate, yearQuarter.firstDate()); + assertEquals(expectedLastDate, yearQuarter.lastDate()); + } + { + final int quarterValue = 2; + YearQuarter yearQuarter = YearQuarter.of(year, quarterValue); + + LocalDate expectedFirstDate = LocalDate.of(year, 4, 1); + log.info("{} - expectedFirstDate: {}", yearQuarter, expectedFirstDate); + LocalDate expectedLastDate = LocalDate.of(year, 6, 30); + log.info("{} - expectedLastDate: {}", yearQuarter, expectedLastDate); + + assertEquals(expectedFirstDate, yearQuarter.firstDate()); + assertEquals(expectedLastDate, yearQuarter.lastDate()); + } + { + final int quarterValue = 3; + YearQuarter yearQuarter = YearQuarter.of(year, quarterValue); + + LocalDate expectedFirstDate = LocalDate.of(year, 7, 1); + log.info("{} - expectedFirstDate: {}", yearQuarter, expectedFirstDate); + LocalDate expectedLastDate = LocalDate.of(year, 9, 30); + log.info("{} - expectedLastDate: {}", yearQuarter, expectedLastDate); + + assertEquals(expectedFirstDate, yearQuarter.firstDate()); + assertEquals(expectedLastDate, yearQuarter.lastDate()); + } + { + final int quarterValue = 4; + YearQuarter yearQuarter = YearQuarter.of(year, quarterValue); + + LocalDate expectedFirstDate = LocalDate.of(year, 10, 1); + log.info("{} - expectedFirstDate: {}", yearQuarter, expectedFirstDate); + LocalDate expectedLastDate = LocalDate.of(year, 12, 31); + log.info("{} - expectedLastDate: {}", yearQuarter, expectedLastDate); + + assertEquals(expectedFirstDate, yearQuarter.firstDate()); + assertEquals(expectedLastDate, yearQuarter.lastDate()); + } + } + + // ================================ + // #endregion - firstDate & lastDate + // ================================ + + // ================================ + // #region - firstYearMonth & lastYearMonth + // ================================ + + @ParameterizedTest + @ValueSource(ints = { 1949, 1990, 2000, 2008, 2023, 2024, Year.MIN_VALUE, Year.MAX_VALUE }) + void test_firstYearMonth_And_lastYearMonth(int year) { YearQuarter yq; yq = YearQuarter.of(year, Quarter.Q1); @@ -102,6 +837,14 @@ public class YearQuarterTests { assertEquals(YearMonth.of(year, 12), yq.lastYearMonth()); } + // ================================ + // #endregion - firstYearMonth & lastYearMonth + // ================================ + + // ================================ + // #region - compareTo + // ================================ + @Test void testCompareTo() { int year1; @@ -124,23 +867,20 @@ public class YearQuarterTests { // 同年同季度 assertEquals(yearQuarter1, yearQuarter2); assertEquals(0, yearQuarter1.compareTo(yearQuarter2)); - } - else if (quarter1 < quarter2) { + } else if (quarter1 < quarter2) { assertNotEquals(yearQuarter1, yearQuarter2); assertTrue(yearQuarter1.isBefore(yearQuarter2)); assertFalse(yearQuarter1.isAfter(yearQuarter2)); assertFalse(yearQuarter2.isBefore(yearQuarter1)); assertTrue(yearQuarter2.isAfter(yearQuarter1)); - } - else if (quarter1 > quarter2) { + } else if (quarter1 > quarter2) { assertNotEquals(yearQuarter1, yearQuarter2); assertFalse(yearQuarter1.isBefore(yearQuarter2)); assertTrue(yearQuarter1.isAfter(yearQuarter2)); assertTrue(yearQuarter2.isBefore(yearQuarter1)); assertFalse(yearQuarter2.isAfter(yearQuarter1)); } - } - else { + } else { // 不同年 assertEquals(year1 - year2, yearQuarter1.compareTo(yearQuarter2)); assertNotEquals(0, yearQuarter1.compareTo(yearQuarter2)); @@ -150,8 +890,7 @@ public class YearQuarterTests { assertFalse(yearQuarter1.isAfter(yearQuarter2)); assertFalse(yearQuarter2.isBefore(yearQuarter1)); assertTrue(yearQuarter2.isAfter(yearQuarter1)); - } - else if (year1 > year2) { + } else if (year1 > year2) { assertNotEquals(yearQuarter1, yearQuarter2); assertFalse(yearQuarter1.isBefore(yearQuarter2)); assertTrue(yearQuarter1.isAfter(yearQuarter2)); @@ -162,4 +901,21 @@ public class YearQuarterTests { } } } + + // ================================ + // #endregion - compareTo + // ================================ + + @Test + void testPlusQuarters() { + int[] array = IntStream.range(0, 100).toArray(); + YearQuarter yq1 = YearQuarter.of(2024, 1); + YearQuarter yq2 = YearQuarter.of(2024, 2); + YearQuarter yq3 = YearQuarter.of(2024, 3); + YearQuarter yq4 = YearQuarter.of(2024, 4); + for (int i : array) { + final int x = i; + // TODO + } + } }