diff --git a/src/main/java/xyz/zhouxy/plusone/commons/util/DateTimeTools.java b/src/main/java/xyz/zhouxy/plusone/commons/util/DateTimeTools.java index 28e1989..e580706 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/util/DateTimeTools.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/util/DateTimeTools.java @@ -16,6 +16,8 @@ package xyz.zhouxy.plusone.commons.util; +import static java.time.temporal.ChronoField.*; + import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; @@ -30,7 +32,6 @@ import java.util.Calendar; import java.util.Date; import java.util.TimeZone; -import com.google.common.base.Strings; import com.google.common.collect.Range; import xyz.zhouxy.plusone.commons.time.Quarter; @@ -46,29 +47,27 @@ public class DateTimeTools { // #region - toString public static String toYearString(int year) { - return Integer.toString(year); + return Integer.toString(YEAR.checkValidIntValue(year)); } public static String toYearString(Year year) { return year.toString(); } - public static String toMonthString(int monthValue) { - return Strings.padStart(Integer.toString(monthValue), 2, '0'); + public static String toMonthStringM(int monthValue) { + return Integer.toString(MONTH_OF_YEAR.checkValidIntValue(monthValue)); } - public static String toMonthString(int monthValue, boolean padStart) { - return padStart ? toMonthString(monthValue) : Integer.toString(monthValue); + public static String toMonthStringMM(int monthValue) { + return String.format("%02d", MONTH_OF_YEAR.checkValidIntValue(monthValue)); } - public static String toMonthString(Month month) { - final int monthValue = month.getValue(); - return Strings.padStart(Integer.toString(monthValue), 2, '0'); + public static String toMonthStringM(Month month) { + return Integer.toString(month.getValue()); } - public static String toMonthString(Month month, boolean padStart) { - final int monthValue = month.getValue(); - return padStart ? toMonthString(month) : Integer.toString(monthValue); + public static String toMonthStringMM(Month month) { + return String.format("%02d", month.getValue()); } // #endregion @@ -282,7 +281,7 @@ public class DateTimeTools { * @param zone 时区 * @return 带时区的地区时间 */ - public static ZonedDateTime toZonedDateTime(LocalDateTime localDateTime, ZoneId zone) { // NOSONAR + public static ZonedDateTime toZonedDateTime(LocalDateTime localDateTime, ZoneId zone) { return ZonedDateTime.of(localDateTime, zone); } diff --git a/src/test/java/xyz/zhouxy/plusone/commons/util/DateTimeToolsTests.java b/src/test/java/xyz/zhouxy/plusone/commons/util/DateTimeToolsTests.java index 370c0eb..a1796bf 100644 --- a/src/test/java/xyz/zhouxy/plusone/commons/util/DateTimeToolsTests.java +++ b/src/test/java/xyz/zhouxy/plusone/commons/util/DateTimeToolsTests.java @@ -17,96 +17,480 @@ package xyz.zhouxy.plusone.commons.util; 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.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import java.time.DateTimeException; import java.time.Instant; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.LocalTime; import java.time.Month; +import java.time.Year; +import java.time.YearMonth; import java.time.ZoneId; import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.collect.Range; + +import xyz.zhouxy.plusone.commons.time.Quarter; +import xyz.zhouxy.plusone.commons.time.YearQuarter; + class DateTimeToolsTests { private static final Logger log = LoggerFactory.getLogger(DateTimeToolsTests.class); - @Test - void testToJoda() { - LocalDateTime dt = LocalDateTime.of(2008, 8, 8, 20, 18, 59, 108000000); - log.info("src: {}", dt); - org.joda.time.LocalDateTime dt2 = DateTimeTools.toJodaLocalDateTime(dt); - log.info("result: {}", dt2); - org.joda.time.format.DateTimeFormatter f = org.joda.time.format.DateTimeFormat - .forPattern("yyyy-MM-dd HH:mm:ss.SSS"); + // Java + static final LocalDateTime LOCAL_DATE_TIME = LocalDateTime.of(2024, 12, 29, 12, 58, 30, 333000000); + static final LocalDate LOCAL_DATE = LOCAL_DATE_TIME.toLocalDate(); + static final LocalTime LOCAL_TIME = LOCAL_DATE_TIME.toLocalTime(); - assertEquals("2008-08-08 20:18:59.108", f.print(dt2)); + // Java - 2024-12-29 12:58:30.333333333 SystemDefaultZone + static final ZoneId SYS_ZONE_ID = ZoneId.systemDefault(); + static final ZonedDateTime ZONED_DATE_TIME_WITH_SYS_ZONE = LOCAL_DATE_TIME.atZone(SYS_ZONE_ID); + static final Instant INSTANT_WITH_SYS_ZONE = ZONED_DATE_TIME_WITH_SYS_ZONE.toInstant(); + static final long INSTANT_MILLIS = INSTANT_WITH_SYS_ZONE.toEpochMilli(); + + static final TimeZone SYS_TIME_ZONE = TimeZone.getDefault(); + static final Date SYS_DATE = Date.from(INSTANT_WITH_SYS_ZONE); + static final Calendar SYS_CALENDAR = Calendar.getInstance(SYS_TIME_ZONE); + static { + SYS_CALENDAR.setTime(SYS_DATE); + } + + // Java - 2024-12-29 12:58:30.333333333 GMT+04:00 + static final ZoneId ZONE_ID = ZoneId.of("GMT+04:00"); + static final ZonedDateTime ZONED_DATE_TIME = LOCAL_DATE_TIME.atZone(ZONE_ID); + static final Instant INSTANT = ZONED_DATE_TIME.toInstant(); + static final long MILLIS = INSTANT.toEpochMilli(); + + static final TimeZone TIME_ZONE = TimeZone.getTimeZone(ZONE_ID); + static final Date DATE = Date.from(INSTANT); + static final Calendar CALENDAR = Calendar.getInstance(TIME_ZONE); + static { + CALENDAR.setTime(DATE); + } + + // Joda + static final org.joda.time.LocalDateTime JODA_LOCAL_DATE_TIME + = new org.joda.time.LocalDateTime(2024, 12, 29, 12, 58, 30, 333); + static final org.joda.time.LocalDate JODA_LOCAL_DATE = JODA_LOCAL_DATE_TIME.toLocalDate(); + static final org.joda.time.LocalTime JODA_LOCAL_TIME = JODA_LOCAL_DATE_TIME.toLocalTime(); + + // Joda - 2024-12-29 12:58:30.333 SystemDefaultZone + static final org.joda.time.DateTimeZone JODA_SYS_ZONE = org.joda.time.DateTimeZone.getDefault(); + static final org.joda.time.DateTime JODA_DATE_TIME_WITH_SYS_ZONE = JODA_LOCAL_DATE_TIME.toDateTime(JODA_SYS_ZONE); + static final org.joda.time.Instant JODA_INSTANT_WITH_SYS_ZONE = JODA_DATE_TIME_WITH_SYS_ZONE.toInstant(); + static final long JODA_INSTANT_MILLIS = JODA_INSTANT_WITH_SYS_ZONE.getMillis(); + + // Joda - 2024-12-29 12:58:30.333 GMT+04:00 + static final org.joda.time.DateTimeZone JODA_ZONE = org.joda.time.DateTimeZone.forID("GMT+04:00"); + static final org.joda.time.DateTime JODA_DATE_TIME = JODA_LOCAL_DATE_TIME.toDateTime(JODA_ZONE); + static final org.joda.time.Instant JODA_INSTANT = JODA_DATE_TIME.toInstant(); + static final long JODA_MILLIS = JODA_INSTANT.getMillis(); + + // ================================ + // #region - toDate + // ================================ + + @Test + void toDate_timeMillis() { + assertNotEquals(SYS_DATE, DATE); + log.info("SYS_DATE: {}, DATE: {}", SYS_DATE, DATE); + assertEquals(SYS_DATE, JODA_DATE_TIME_WITH_SYS_ZONE.toDate()); + assertEquals(SYS_DATE, DateTimeTools.toDate(INSTANT_MILLIS)); + assertEquals(DATE, JODA_DATE_TIME.toDate()); + assertEquals(DATE, DateTimeTools.toDate(MILLIS)); } @Test - void testToInstant() { - ZonedDateTime dt = ZonedDateTime.of(2008, 1, 8, 10, 23, 50, 108000000, ZoneId.systemDefault()); - Instant instant = DateTimeTools.toInstant(dt.toInstant().toEpochMilli()); - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yy-M-d HH:mm:ss.SSS"); - String str = formatter.format(instant.atZone(ZoneId.systemDefault())); - log.info(str); - assertEquals("08-1-8 10:23:50.108", str); + void toDate_calendar() { + assertEquals(SYS_DATE, DateTimeTools.toDate(SYS_CALENDAR)); + assertEquals(DATE, DateTimeTools.toDate(CALENDAR)); } @Test - void testToJodaDateTime() { - ZonedDateTime dt = ZonedDateTime.of(2008, 1, 8, 10, 23, 50, 108000000, ZoneId.systemDefault()); - Instant instant = DateTimeTools.toInstant(dt.toInstant().toEpochMilli()); - - org.joda.time.format.DateTimeFormatter f = org.joda.time.format.DateTimeFormat - .forPattern("yyyy-MM-dd HH:mm:ss.SSS"); - - org.joda.time.DateTime jodaDateTime = DateTimeTools.toJodaDateTime(instant, ZoneId.of("+08:00")); - log.info("jodaDateTime: {}", jodaDateTime); - assertEquals("2008-01-08 10:23:50.108", f.print(jodaDateTime)); - - jodaDateTime = DateTimeTools.toJodaDateTime(instant, ZoneId.of("+02:00")); - log.info("jodaDateTime: {}", jodaDateTime); - assertEquals("2008-01-08 04:23:50.108", f.print(jodaDateTime)); + void toDate_instant() { + assertEquals(SYS_DATE, DateTimeTools.toDate(INSTANT_WITH_SYS_ZONE)); + assertEquals(DATE, DateTimeTools.toDate(INSTANT)); } @Test - void test() { - java.time.Instant now = java.time.Instant.now(); - org.joda.time.DateTime jodaDateTime = DateTimeTools.toJodaDateTime(now, ZoneId.of("America/New_York")); - org.joda.time.format.DateTimeFormatter formatter = org.joda.time.format.DateTimeFormat - .forPattern("yyyy-MM-dd HH:mm:ss.SSS"); - log.info(formatter.print(jodaDateTime)); - log.info(jodaDateTime.getZone().toString()); - log.info(jodaDateTime.toString()); - log.info("=========================================="); - org.joda.time.Instant instant = new org.joda.time.Instant(System.currentTimeMillis() - 500000); - log.info(instant.toString()); - log.info(DateTimeTools.toJavaInstant(instant).toString()); - log.info(DateTimeTools.toZonedDateTime(instant, org.joda.time.DateTimeZone.forID("America/New_York")) - .toString()); + void toDate_ZoneDateTime() { + assertEquals(SYS_DATE, DateTimeTools.toDate(ZONED_DATE_TIME_WITH_SYS_ZONE)); + assertEquals(DATE, DateTimeTools.toDate(ZONED_DATE_TIME)); } @Test - void testToJodaInstant() { - java.time.Instant javaInstant = java.time.Instant.now(); - log.info("javaInstant: {}", javaInstant); - - org.joda.time.Instant jodaInstant = DateTimeTools.toJodaInstant(javaInstant); - log.info("jodaInstant: {}", jodaInstant); - - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"); - DateTimeFormatter formatter2 = formatter.withZone(ZoneId.systemDefault()); - log.info("{}", formatter); - log.info("{}", formatter2); + void toDate_LocalDateTimeAndZoneId() { + assertEquals(SYS_DATE, DateTimeTools.toDate(LOCAL_DATE_TIME, SYS_ZONE_ID)); + assertEquals(DATE, DateTimeTools.toDate(LOCAL_DATE_TIME, ZONE_ID)); + assertEquals(SYS_DATE, DateTimeTools.toDate(LOCAL_DATE, LOCAL_TIME, SYS_ZONE_ID)); + assertEquals(DATE, DateTimeTools.toDate(LOCAL_DATE, LOCAL_TIME, ZONE_ID)); } + // ================================ + // #endregion - toDate + // ================================ + + // ================================ + // #region - toInstant + // ================================ + + @Test + void toInstant_timeMillis() { + assertEquals(INSTANT_WITH_SYS_ZONE, DateTimeTools.toInstant(INSTANT_MILLIS)); + assertEquals(INSTANT, DateTimeTools.toInstant(MILLIS)); + } + + @Test + void toInstant_Date() { + assertEquals(INSTANT_WITH_SYS_ZONE, DateTimeTools.toInstant(SYS_DATE)); + assertEquals(INSTANT, DateTimeTools.toInstant(DATE)); + } + + @Test + void toInstant_Calendar() { + assertEquals(INSTANT_WITH_SYS_ZONE, DateTimeTools.toInstant(SYS_CALENDAR)); + assertEquals(INSTANT, DateTimeTools.toInstant(CALENDAR)); + } + + @Test + void toInstant_ZonedDateTime() { + assertEquals(INSTANT_WITH_SYS_ZONE, DateTimeTools.toInstant(ZONED_DATE_TIME_WITH_SYS_ZONE)); + assertEquals(INSTANT, DateTimeTools.toInstant(ZONED_DATE_TIME)); + } + + @Test + void toInstant_LocalDateTimeAndZone() { + assertEquals(INSTANT_WITH_SYS_ZONE, DateTimeTools.toInstant(LOCAL_DATE_TIME, SYS_ZONE_ID)); + assertEquals(INSTANT, DateTimeTools.toInstant(LOCAL_DATE_TIME, ZONE_ID)); + } + + // ================================ + // #endregion - toInstant + // ================================ + + // ================================ + // #region - toZonedDateTime + // ================================ + + @Test + void toZonedDateTime_TimeMillisAndZone() { + assertEquals(ZONED_DATE_TIME_WITH_SYS_ZONE, DateTimeTools.toZonedDateTime(INSTANT_MILLIS, SYS_ZONE_ID)); + assertEquals(ZONED_DATE_TIME, DateTimeTools.toZonedDateTime(MILLIS, ZONE_ID)); + } + + @Test + void toZonedDateTime_DateAndZoneId() { + assertEquals(ZONED_DATE_TIME_WITH_SYS_ZONE, DateTimeTools.toZonedDateTime(SYS_DATE, SYS_ZONE_ID)); + assertEquals(ZONED_DATE_TIME, DateTimeTools.toZonedDateTime(DATE, ZONE_ID)); + } + + @Test + void toZonedDateTime_DateAndTimeZone() { + assertEquals(ZONED_DATE_TIME_WITH_SYS_ZONE, DateTimeTools.toZonedDateTime(SYS_DATE, SYS_TIME_ZONE)); + assertEquals(ZONED_DATE_TIME, DateTimeTools.toZonedDateTime(DATE, TIME_ZONE)); + } + + @Test + void toZonedDateTime_Calendar() { + assertEquals(ZONED_DATE_TIME_WITH_SYS_ZONE, DateTimeTools.toZonedDateTime(SYS_CALENDAR)); + assertEquals(ZONED_DATE_TIME, DateTimeTools.toZonedDateTime(CALENDAR)); + } + + @Test + void toZonedDateTime_CalendarAndZoneId() { + assertEquals(ZONED_DATE_TIME_WITH_SYS_ZONE, DateTimeTools.toZonedDateTime(SYS_CALENDAR, SYS_ZONE_ID)); + assertEquals(ZONED_DATE_TIME, DateTimeTools.toZonedDateTime(CALENDAR, ZONE_ID)); + } + + @Test + void toZonedDateTime_CalendarAndTimeZone() { + assertEquals(ZONED_DATE_TIME_WITH_SYS_ZONE, DateTimeTools.toZonedDateTime(SYS_CALENDAR, SYS_TIME_ZONE)); + assertEquals(ZONED_DATE_TIME, DateTimeTools.toZonedDateTime(CALENDAR, TIME_ZONE)); + } + + @Test + void toZonedDateTime_LocalDateTimeAndZoneId() { + assertEquals(ZONED_DATE_TIME_WITH_SYS_ZONE, DateTimeTools.toZonedDateTime(LOCAL_DATE_TIME, SYS_ZONE_ID)); + assertEquals(ZONED_DATE_TIME, DateTimeTools.toZonedDateTime(LOCAL_DATE_TIME, ZONE_ID)); + } + + // ================================ + // #endregion - toZonedDateTime + // ================================ + + // ================================ + // #region - toLocalDateTime + // ================================ + + @Test + void toLocalDateTime_TimeMillisAndZoneId() { + assertEquals(LOCAL_DATE_TIME, DateTimeTools.toLocalDateTime(INSTANT_MILLIS, SYS_ZONE_ID)); + assertEquals(LOCAL_DATE_TIME, DateTimeTools.toLocalDateTime(MILLIS, ZONE_ID)); + } + + @Test + void toLocalDateTime_DateAndZoneId() { + assertEquals(LOCAL_DATE_TIME, DateTimeTools.toLocalDateTime(SYS_DATE, SYS_ZONE_ID)); + assertEquals(LOCAL_DATE_TIME, DateTimeTools.toLocalDateTime(DATE, ZONE_ID)); + } + + @Test + void toLocalDateTime_DateAndTimeZone() { + assertEquals(LOCAL_DATE_TIME, DateTimeTools.toLocalDateTime(SYS_DATE, SYS_TIME_ZONE)); + assertEquals(LOCAL_DATE_TIME, DateTimeTools.toLocalDateTime(DATE, TIME_ZONE)); + } + + @Test + void toLocalDateTime_CalendarAndZoneId() { + assertEquals(LOCAL_DATE_TIME, DateTimeTools.toLocalDateTime(SYS_CALENDAR, SYS_ZONE_ID)); + assertEquals(LOCAL_DATE_TIME, DateTimeTools.toLocalDateTime(CALENDAR, ZONE_ID)); + } + + @Test + void toLocalDateTime_CalendarAndTimeZone() { + assertEquals(LOCAL_DATE_TIME, DateTimeTools.toLocalDateTime(SYS_CALENDAR, SYS_TIME_ZONE)); + assertEquals(LOCAL_DATE_TIME, DateTimeTools.toLocalDateTime(CALENDAR, TIME_ZONE)); + } + + @Test + void toLocalDateTime_ZonedDateTimeAndZoneId() { + assertEquals(LOCAL_DATE_TIME, DateTimeTools.toLocalDateTime(ZONED_DATE_TIME_WITH_SYS_ZONE, SYS_ZONE_ID)); + assertEquals(LOCAL_DATE_TIME, DateTimeTools.toLocalDateTime(ZONED_DATE_TIME, ZONE_ID)); + } + + // ================================ + // #endregion - toLocalDateTime + // ================================ + + // ================================ + // #region - toJodaInstant + // ================================ + + @Test + void toJodaInstant_JavaInstant() { + assertEquals(JODA_INSTANT_WITH_SYS_ZONE, DateTimeTools.toJodaInstant(INSTANT_WITH_SYS_ZONE)); + assertEquals(JODA_INSTANT, DateTimeTools.toJodaInstant(INSTANT)); + } + + @Test + void toJodaInstant_ZonedDateTime() { + assertEquals(JODA_INSTANT_WITH_SYS_ZONE, DateTimeTools.toJodaInstant(ZONED_DATE_TIME_WITH_SYS_ZONE)); + assertEquals(JODA_INSTANT, DateTimeTools.toJodaInstant(ZONED_DATE_TIME)); + } + + @Test + void toJodaInstant_LocalDateTimeAndZoneId() { + assertEquals(JODA_INSTANT_WITH_SYS_ZONE, DateTimeTools.toJodaInstant(LOCAL_DATE_TIME, SYS_ZONE_ID)); + assertEquals(JODA_INSTANT, DateTimeTools.toJodaInstant(LOCAL_DATE_TIME, ZONE_ID)); + } + + // ================================ + // #endregion - toJodaInstant + // ================================ + + // ================================ + // #region - toJavaInstant + // ================================ + + @Test + void toJavaInstant_JodaInstant() { + assertEquals(INSTANT_WITH_SYS_ZONE, DateTimeTools.toJavaInstant(JODA_INSTANT_WITH_SYS_ZONE)); + assertEquals(INSTANT, DateTimeTools.toJavaInstant(JODA_INSTANT)); + } + + @Test + void toJavaInstant_JodaDateTime() { + assertEquals(INSTANT_WITH_SYS_ZONE, DateTimeTools.toJavaInstant(JODA_DATE_TIME_WITH_SYS_ZONE)); + assertEquals(INSTANT, DateTimeTools.toJavaInstant(JODA_DATE_TIME)); + } + + @Test + void toJavaInstant_JodaLocalDateTimeAndJodaDateTimeZone() { + assertEquals(INSTANT_WITH_SYS_ZONE, DateTimeTools.toJavaInstant(JODA_LOCAL_DATE_TIME, JODA_SYS_ZONE)); + assertEquals(INSTANT, DateTimeTools.toJavaInstant(JODA_LOCAL_DATE_TIME, JODA_ZONE)); + } + + // ================================ + // #endregion - toJavaInstant + // ================================ + + // ================================ + // #region - toJodaDateTime + // ================================ + + @Test + void toJodaDateTime_ZonedDateTime() { + assertEquals(JODA_DATE_TIME_WITH_SYS_ZONE, DateTimeTools.toJodaDateTime(ZONED_DATE_TIME_WITH_SYS_ZONE)); + assertEquals(JODA_DATE_TIME, DateTimeTools.toJodaDateTime(ZONED_DATE_TIME)); + } + + @Test + void toJodaDateTime_LocalDateTimeAndZoneId() { + assertEquals(JODA_DATE_TIME_WITH_SYS_ZONE, DateTimeTools.toJodaDateTime(LOCAL_DATE_TIME, SYS_ZONE_ID)); + assertEquals(JODA_DATE_TIME, DateTimeTools.toJodaDateTime(LOCAL_DATE_TIME, ZONE_ID)); + } + + @Test + void toJodaDateTime_InstantAndZoneId() { + assertEquals(JODA_DATE_TIME_WITH_SYS_ZONE, DateTimeTools.toJodaDateTime(INSTANT_WITH_SYS_ZONE, SYS_ZONE_ID)); + assertEquals(JODA_DATE_TIME, DateTimeTools.toJodaDateTime(INSTANT, ZONE_ID)); + } + + // ================================ + // #endregion - toJodaDateTime + // ================================ + + // ================================ + // #region - toZonedDateTime + // ================================ + + @Test + void toZonedDateTime_JodaDateTime() { + assertEquals(ZONED_DATE_TIME_WITH_SYS_ZONE, DateTimeTools.toZonedDateTime(JODA_DATE_TIME_WITH_SYS_ZONE)); + assertEquals(ZONED_DATE_TIME, DateTimeTools.toZonedDateTime(JODA_DATE_TIME)); + } + + @Test + void toZonedDateTime_JodaLocalDateTimeAndJodaDateTimeZone() { + assertEquals(ZONED_DATE_TIME_WITH_SYS_ZONE, DateTimeTools.toZonedDateTime(JODA_LOCAL_DATE_TIME, JODA_SYS_ZONE)); + assertEquals(ZONED_DATE_TIME, DateTimeTools.toZonedDateTime(JODA_LOCAL_DATE_TIME, JODA_ZONE)); + } + + @Test + void toZonedDateTime_JodaInstantAndJodaDateTimeZone() { + assertEquals(ZONED_DATE_TIME_WITH_SYS_ZONE, DateTimeTools.toZonedDateTime(JODA_INSTANT_WITH_SYS_ZONE, JODA_SYS_ZONE)); + assertEquals(ZONED_DATE_TIME, DateTimeTools.toZonedDateTime(JODA_INSTANT, JODA_ZONE)); + } + + // ================================ + // #endregion - toZonedDateTime + // ================================ + + // ================================ + // #region - toJodaLocalDateTime + // ================================ + + @Test + void toJodaLocalDateTime_JavaLocalDateTime() { + assertEquals(JODA_LOCAL_DATE_TIME, DateTimeTools.toJodaLocalDateTime(LOCAL_DATE_TIME)); + } + + @Test + void toJavaLocalDateTime_JodaLocalDateTime() { + assertEquals(LOCAL_DATE_TIME, DateTimeTools.toJavaLocalDateTime(JODA_LOCAL_DATE_TIME)); + } + + // ================================ + // #endregion - toJodaLocalDateTime + // ================================ + + // ================================ + // #region - ZondId <--> DateTimeZone + // ================================ + + @Test + void convertJavaZoneIdAndJodaDateTimeZone() { + assertEquals(SYS_ZONE_ID, DateTimeTools.toJavaZone(JODA_SYS_ZONE)); + assertEquals(ZONE_ID, DateTimeTools.toJavaZone(JODA_ZONE)); + assertEquals(JODA_SYS_ZONE, DateTimeTools.toJodaZone(SYS_ZONE_ID)); + assertEquals(JODA_ZONE, DateTimeTools.toJodaZone(ZONE_ID)); + } + + // ================================ + // #endregion - ZondId <--> DateTimeZone + // ================================ + + // ================================ + // #region - YearQuarter & Quarter + // ================================ + + @Test + void getQuarter() { + YearQuarter expectedYearQuarter = YearQuarter.of(2024, 4); + assertEquals(expectedYearQuarter, DateTimeTools.getQuarter(SYS_DATE)); + assertEquals(expectedYearQuarter, DateTimeTools.getQuarter(SYS_CALENDAR)); + assertEquals(Quarter.Q4, DateTimeTools.getQuarter(Month.DECEMBER)); + assertEquals(expectedYearQuarter, DateTimeTools.getQuarter(2024, Month.DECEMBER)); + assertEquals(expectedYearQuarter, DateTimeTools.getQuarter(YearMonth.of(2024, Month.DECEMBER))); + assertEquals(expectedYearQuarter, DateTimeTools.getQuarter(LOCAL_DATE)); + } + + // ================================ + // #endregion - YearQuarter & Quarter + // ================================ + + // ================================ + // #region - others + // ================================ + + @Test + void startDateOfYear() { + assertEquals(LocalDate.of(2008, 1, 1), DateTimeTools.startDateOfYear(2008)); + assertEquals(LocalDate.of(2008, 12, 31), DateTimeTools.endDateOfYear(2008)); + assertEquals(LocalDateTime.of(2024, 12, 30, 0, 0, 0), + DateTimeTools.startOfNextDate(LOCAL_DATE)); + assertEquals(LocalDateTime.of(2024, 12, 30, 0, 0, 0).atZone(SYS_ZONE_ID), + DateTimeTools.startOfNextDate(LOCAL_DATE, SYS_ZONE_ID)); + assertEquals(LocalDateTime.of(2024, 12, 30, 0, 0, 0).atZone(ZONE_ID), + DateTimeTools.startOfNextDate(LOCAL_DATE, ZONE_ID)); + + Range localDateTimeRange = DateTimeTools.toDateTimeRange(LOCAL_DATE); + assertEquals(LOCAL_DATE.atStartOfDay(), localDateTimeRange.lowerEndpoint()); + assertTrue(localDateTimeRange.contains(LOCAL_DATE.atStartOfDay())); + assertEquals(LocalDate.of(2024, 12, 30).atStartOfDay(), localDateTimeRange.upperEndpoint()); + assertEquals(LocalDate.of(2024, 12, 30).atStartOfDay(), localDateTimeRange.upperEndpoint()); + assertFalse(localDateTimeRange.contains(LocalDate.of(2024, 12, 30).atStartOfDay())); + + Range zonedDateTimeRange = DateTimeTools.toDateTimeRange(LOCAL_DATE, SYS_ZONE_ID); + assertEquals(LOCAL_DATE.atStartOfDay().atZone(SYS_ZONE_ID), zonedDateTimeRange.lowerEndpoint()); + assertTrue(zonedDateTimeRange.contains(LOCAL_DATE.atStartOfDay().atZone(SYS_ZONE_ID))); + assertEquals(ZonedDateTime.of(LocalDate.of(2024, 12, 30).atStartOfDay(), SYS_ZONE_ID), zonedDateTimeRange.upperEndpoint()); + assertEquals(ZonedDateTime.of(LocalDate.of(2024, 12, 30).atStartOfDay(), SYS_ZONE_ID), zonedDateTimeRange.upperEndpoint()); + assertFalse(zonedDateTimeRange.contains(LocalDate.of(2024, 12, 30).atStartOfDay().atZone(SYS_ZONE_ID))); + } + + // ================================ + // #endregion - others + // ================================ + + // ================================ + // #region - toString + // ================================ + @Test void testToString() { - assertEquals("04", DateTimeTools.toMonthString(Month.APRIL)); - assertEquals("04", DateTimeTools.toMonthString(Month.APRIL, true)); - assertEquals("4", DateTimeTools.toMonthString(Month.APRIL, false)); + assertEquals("2024", DateTimeTools.toYearString(2024)); + assertEquals("999999999", DateTimeTools.toYearString(Year.MAX_VALUE)); + assertEquals("-999999999", DateTimeTools.toYearString(Year.MIN_VALUE)); + assertThrows(DateTimeException.class, () -> DateTimeTools.toYearString(Year.MIN_VALUE - 1)); + assertThrows(DateTimeException.class, () -> DateTimeTools.toYearString(Year.MAX_VALUE + 1)); + + assertEquals("01", DateTimeTools.toMonthStringMM(1)); + assertEquals("02", DateTimeTools.toMonthStringMM(2)); + assertEquals("3", DateTimeTools.toMonthStringM(3)); + assertEquals("04", DateTimeTools.toMonthStringMM(Month.APRIL)); + assertEquals("05", DateTimeTools.toMonthStringMM(Month.MAY)); + assertEquals("6", DateTimeTools.toMonthStringM(Month.JUNE)); + + assertThrows(DateTimeException.class, () -> DateTimeTools.toMonthStringM(0)); + assertThrows(DateTimeException.class, () -> DateTimeTools.toMonthStringMM(0)); + assertThrows(DateTimeException.class, () -> DateTimeTools.toMonthStringM(13)); + assertThrows(DateTimeException.class, () -> DateTimeTools.toMonthStringMM(13)); } + + // ================================ + // #endregion - toString + // ================================ } diff --git a/src/test/java/xyz/zhouxy/plusone/commons/util/IdGeneratorTests.java b/src/test/java/xyz/zhouxy/plusone/commons/util/IdGeneratorTests.java index 7447e48..ccc3f59 100644 --- a/src/test/java/xyz/zhouxy/plusone/commons/util/IdGeneratorTests.java +++ b/src/test/java/xyz/zhouxy/plusone/commons/util/IdGeneratorTests.java @@ -25,6 +25,8 @@ import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import cn.hutool.core.collection.ConcurrentHashSet; @@ -49,9 +51,12 @@ public class IdGeneratorTests { } } - @Test - void testIdWorker() { // NOSONAR - final IdWorker idWorker = new IdWorker(0L); + @ParameterizedTest + @ValueSource(longs = { 0L, 1L, 108L, 300L }) + void testIdWorker(long workerId) { // NOSONAR + // 如果使用 new IdWorker(0L) 创建,会和下面的 IdGenerator#nextSnowflakeId 使用相同 workerId 的不同 IdWorker 实例,造成 ID 重复 + final IdWorker idWorker = IdGenerator.getSnowflakeIdGenerator(workerId); + final Set ids = new ConcurrentHashSet<>(); for (int i = 0; i < 10000; i++) { executor.execute(() -> { @@ -63,7 +68,7 @@ public class IdGeneratorTests { }); executor.execute(() -> { for (int j = 0; j < 50000; j++) { - if (false == ids.add(IdGenerator.nextSnowflakeId(0))) { + if (false == ids.add(IdGenerator.nextSnowflakeId(workerId))) { throw new RuntimeException("重复ID!"); } } diff --git a/src/test/java/xyz/zhouxy/plusone/commons/util/RegexToolsTests.java b/src/test/java/xyz/zhouxy/plusone/commons/util/RegexToolsTests.java index 3968a24..0d3fb8d 100644 --- a/src/test/java/xyz/zhouxy/plusone/commons/util/RegexToolsTests.java +++ b/src/test/java/xyz/zhouxy/plusone/commons/util/RegexToolsTests.java @@ -39,7 +39,7 @@ class RegexToolsTests { @Test void getPattern_CachePatternFalse_ReturnsNewPattern() { - String pattern = "abc"; + String pattern = "getPattern_CachePatternFalse_ReturnsNewPattern"; Pattern pattern1 = RegexTools.getPattern(pattern, false); Pattern pattern2 = RegexTools.getPattern(pattern, false); assertNotSame(pattern1, pattern2, "Pattern should not be cached"); @@ -63,7 +63,7 @@ class RegexToolsTests { @Test void getPatterns_CachePatternFalse_ReturnsNewPatterns() { - String[] patterns = {"abc", "def"}; + String[] patterns = {"getPatterns_CachePatternFalse_ReturnsNewPatterns1", "getPatterns_CachePatternFalse_ReturnsNewPatterns2"}; Pattern[] patterns1 = RegexTools.getPatterns(patterns, false); Pattern[] patterns2 = RegexTools.getPatterns(patterns, false); assertNotSame(patterns1[0], patterns2[0]);