diff --git a/src/main/java/xyz/zhouxy/plusone/commons/base/Quarter.java b/src/main/java/xyz/zhouxy/plusone/commons/base/Quarter.java new file mode 100644 index 0000000..686c692 --- /dev/null +++ b/src/main/java/xyz/zhouxy/plusone/commons/base/Quarter.java @@ -0,0 +1,128 @@ +package xyz.zhouxy.plusone.commons.base; + +import java.time.Month; +import java.time.MonthDay; + +import com.google.common.base.Preconditions; + +import xyz.zhouxy.plusone.commons.util.Numbers; + +public enum Quarter { + Q1(1, "Q1"), + Q2(2, "Q2"), + Q3(3, "Q3"), + Q4(4, "Q4"), + ; + + private final int value; + private final String displayName; + + private final int startMonthValue; + private final MonthDay startMonthDay; + + private final int lastMonthValue; + private final MonthDay lastMonthDay; + + Quarter(int value, String str) { + this.value = value; + this.displayName = str; + + final int lastMonth = value * 3; + final int startMonth = lastMonth - 2; + + this.startMonthValue = startMonth; + this.startMonthDay = MonthDay.of(startMonth, 1); + this.lastMonthValue = lastMonth; + this.lastMonthDay = MonthDay.of(lastMonth, (value == 1 || value == 4) ? 31 : 30); + } + + public static Quarter fromMonth(int monthValue) { + Preconditions.checkArgument(Numbers.between(monthValue, 1, 13), "Invalid value for MonthOfYear: " + monthValue); + return of(computeQuarterValueInternal(monthValue)); + } + + public static Quarter fromMonth(Month month) { + final int monthValue = month.getValue(); + return of(computeQuarterValueInternal(monthValue)); + } + + public final YearQuarter atYear(int year) { + return YearQuarter.of(year, this); + } + + public static Quarter of(int value) { + switch (value) { + case 1: + return Q1; + case 2: + return Q2; + case 3: + return Q3; + case 4: + return Q4; + default: + throw new EnumConstantNotPresentException(Quarter.class, Integer.toString(value)); + } + } + + public static Quarter of(String str) { + switch (str) { + case "Q1": + return Q1; + case "Q2": + return Q2; + case "Q3": + return Q3; + case "Q4": + return Q4; + default: + throw new EnumConstantNotPresentException(Quarter.class, str); + } + } + + // Getters + + public int getValue() { + return value; + } + + public String getDisplayName() { + return displayName; + } + + public Month getStartMonth() { + return Month.of(startMonthValue); + } + + public int getStartMonthValue() { + return startMonthValue; + } + + public Month getLastMonth() { + return Month.of(lastMonthValue); + } + + public int getLastMonthValue() { + return lastMonthValue; + } + + public MonthDay getStartMonthDay() { + return startMonthDay; + } + + public MonthDay getLastMonthDay() { + return lastMonthDay; + } + + // Getters end + + /** + * 计算季度 + * + * @param monthValue 1~12 + * @return 季度。1~4 + */ + private static int computeQuarterValueInternal(int monthValue) { + return (monthValue - 1) / 3 + 1; + } +} diff --git a/src/main/java/xyz/zhouxy/plusone/commons/base/YearQuarter.java b/src/main/java/xyz/zhouxy/plusone/commons/base/YearQuarter.java new file mode 100644 index 0000000..5c75b85 --- /dev/null +++ b/src/main/java/xyz/zhouxy/plusone/commons/base/YearQuarter.java @@ -0,0 +1,80 @@ +package xyz.zhouxy.plusone.commons.base; + +import java.time.LocalDate; +import java.time.Month; +import java.time.YearMonth; +import java.util.Calendar; +import java.util.Date; + +import com.google.common.base.Preconditions; + +public final class YearQuarter { + private final int year; + private final Quarter quarter; + private final LocalDate startDate; + private final LocalDate lastDate; + + private YearQuarter(int year, Quarter quarter) { + Preconditions.checkNotNull(quarter, "Quarter can not be null."); + this.year = year; + this.quarter = quarter; + this.startDate = quarter.getStartMonthDay().atYear(year); + this.lastDate = quarter.getLastMonthDay().atYear(year); + } + + public static YearQuarter of(int year, Quarter quarter) { + return new YearQuarter(year, quarter); + } + + public static YearQuarter of(LocalDate date) { + return new YearQuarter(date.getYear(), Quarter.fromMonth(date.getMonth())); + } + + public static YearQuarter of(Date date) { + @SuppressWarnings("deprecation") + final int year = date.getYear() + 1900; + @SuppressWarnings("deprecation") + final int month = date.getMonth() + 1; + return of(year, Quarter.fromMonth(month)); + } + + public static YearQuarter of(Calendar date) { + return of(date.get(Calendar.YEAR), Quarter.fromMonth(date.get(Calendar.MONTH) + 1)); + } + + public static YearQuarter of(YearMonth yearMonth) { + return of(yearMonth.getYear(), Quarter.fromMonth(yearMonth.getMonth())); + } + + public int getYear() { + return year; + } + + public Quarter getQuarter() { + return quarter; + } + + public Month getStartMonth() { + return this.quarter.getStartMonth(); + } + + public int getStartMonthValue() { + return this.quarter.getStartMonthValue(); + } + + public Month getLastMonth() { + return this.quarter.getLastMonth(); + } + + public int getLastMonthValue() { + return this.quarter.getLastMonthValue(); + } + + public LocalDate getStartDate() { + return startDate; + } + + public LocalDate getLastDate() { + return lastDate; + } +} 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 529f83a..9747778 100644 --- a/src/main/java/xyz/zhouxy/plusone/commons/util/DateTimeTools.java +++ b/src/main/java/xyz/zhouxy/plusone/commons/util/DateTimeTools.java @@ -17,7 +17,8 @@ import org.apache.commons.lang3.StringUtils; import com.google.common.base.Preconditions; import xyz.zhouxy.plusone.commons.collection.SafeConcurrentHashMap; - +import xyz.zhouxy.plusone.commons.base.Quarter; +import xyz.zhouxy.plusone.commons.base.YearQuarter; import xyz.zhouxy.plusone.commons.collection.MapWrapper; public class DateTimeTools { @@ -158,6 +159,10 @@ public class DateTimeTools { return ZonedDateTime.ofInstant(dateTime.toInstant(), timeZone.toZoneId()); } + public static ZonedDateTime toZonedDateTime(Calendar calendar) { + return calendar.toInstant().atZone(calendar.getTimeZone().toZoneId()); + } + public static ZonedDateTime toZonedDateTime(Calendar calendar, ZoneId zone) { return calendar.toInstant().atZone(zone); } @@ -327,30 +332,20 @@ public class DateTimeTools { // getQuarter - @SuppressWarnings("deprecation") - public static int getQuarter(Date date) { - return getQuarterInternal(date.getMonth() + 1); + public static YearQuarter getQuarter(Date date) { + return YearQuarter.of(date); } - public static int getQuarter(Calendar date) { - return getQuarterInternal(date.get(Calendar.MONTH) + 1); + public static YearQuarter getQuarter(Calendar date) { + return YearQuarter.of(date); } - public static int getQuarter(Month month) { - return getQuarterInternal(month.getValue()); + public static Quarter getQuarter(Month month) { + return Quarter.fromMonth(month); } - public static int getQuarter(LocalDate date) { - return getQuarterInternal(date.getMonthValue()); - } - - /** - * 获取季度 - * @param monthValue 1~12 - * @return 季度。1~4 - */ - private static int getQuarterInternal(int monthValue) { - return (monthValue - 1) / 3 + 1; + public static YearQuarter getQuarter(LocalDate date) { + return YearQuarter.of(date); } private DateTimeTools() { 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 912dda6..79c3908 100644 --- a/src/test/java/xyz/zhouxy/plusone/commons/util/DateTimeToolsTests.java +++ b/src/test/java/xyz/zhouxy/plusone/commons/util/DateTimeToolsTests.java @@ -1,8 +1,11 @@ package xyz.zhouxy.plusone.commons.util; +import static org.junit.jupiter.api.Assertions.assertEquals; + import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; +import java.time.ZonedDateTime; import org.junit.jupiter.api.Test; import org.slf4j.Logger; @@ -14,38 +17,56 @@ class DateTimeToolsTests { @Test void testLocalNowStr() { - log.info(DateTimeTools.nowStr("yyyy/MM/dd HH:mm:ss.SSS")); + String nowStr = DateTimeTools.nowStr("yyyy/MM/dd HH:mm:ss.SSS"); + log.info(nowStr); + assertEquals(23, nowStr.length()); } @Test void testToJoda() { - LocalDateTime now = LocalDateTime.now(); - log.info("now: {}", now); - org.joda.time.LocalDateTime now2 = DateTimeTools.toJodaLocalDateTime(now); - log.info("now2: {}", now2); + 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"); + + assertEquals("2008-08-08 20:18:59.108", f.print(dt2)); } @Test void testToInstant() { - Instant now = DateTimeTools.toInstant(System.currentTimeMillis()); - String str = DateTimeTools.toString("yy-M-d HH:mm:ss.SSS", now); + ZonedDateTime dt = ZonedDateTime.of(2008, 1, 8, 10, 23, 50, 108000000, ZoneId.systemDefault()); + Instant instant = DateTimeTools.toInstant(dt.toInstant().toEpochMilli()); + String str = DateTimeTools.toString("yy-M-d HH:mm:ss.SSS", instant); log.info(str); + assertEquals("08-1-8 10:23:50.108", str); } @Test void testToJodaDateTime() { - Instant now = Instant.now(); - org.joda.time.DateTime jodaDateTime = DateTimeTools.toJodaDateTime(now, ZoneId.of("+08:00")); + 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); - jodaDateTime = DateTimeTools.toJodaDateTime(now, ZoneId.of("+02:00")); + 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)); } @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"); + 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());