diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/DateBuilder.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/DateBuilder.java index 3ba56c284..f2f0cc663 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/DateBuilder.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/DateBuilder.java @@ -14,7 +14,6 @@ package org.dromara.hutool.core.date; import java.time.*; import java.util.Calendar; -import java.util.Date; import java.util.TimeZone; import java.util.concurrent.TimeUnit; @@ -402,42 +401,23 @@ public final class DateBuilder { return this; } - /** - * 将当前时间对象转换为{@link Date}类型。此方法根据是否设置了时区偏移量使用不同的转换策略。 - * - * 。 - * - * @return Date 表示当前时间的 Date 对象。 - */ - public Date toDate() { - if (!zoneOffsetSetted) { - // 时区偏移量未设置,使用 Calendar 进行转换 - return toCalendar().getTime(); - } - // 时区偏移量已设置,直接转换为 Date 对象返回 - return Date.from(toOffsetDateTime().toInstant()); - } - /** * 将当前时间对象转换为{@link DateTime}类型。此方法根据是否设置了时区偏移量使用不同的转换策略。 * * 。 * * @return DateTime 表示当前时间的 DateTime 对象。 */ - public DateTime toDateTime() { + public DateTime toDate() { if (!zoneOffsetSetted) { - // 时区偏移量未设置,使用 Calendar 进行转换 - return new DateTime(toCalendar()); + // 时区偏移量未设置,使用 Calendar 进行转换,无需读取时区 + return new DateTime(toCalendar().getTimeInMillis()); } // 时区偏移量已设置,直接转换为 Date 对象返回 - return new DateTime(toOffsetDateTime().toInstant()); + return new DateTime(toOffsetDateTime().toInstant().toEpochMilli()); } /** @@ -495,7 +475,7 @@ public final class DateBuilder { * * @return LocalDateTime 表示当前对象日期时间的LocalDateTime实例。 */ - LocalDateTime toLocalDateTime() { + public LocalDateTime toLocalDateTime() { this.prepare(); if (millisecond > 0) { @@ -537,7 +517,7 @@ public final class DateBuilder { * * @return OffsetDateTime 表示当前时间的 OffsetDateTime 对象。 */ - OffsetDateTime toOffsetDateTime() { + public OffsetDateTime toOffsetDateTime() { this.prepare(); // 准备工作,可能涉及一些初始化或数据处理 if (millisecond > 0) { diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/DateTime.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/DateTime.java index af7a08566..35b78e6de 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/DateTime.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/DateTime.java @@ -38,7 +38,12 @@ import java.util.TimeZone; /** * 包装{@link Date}
* 此类继承了{@link Date},并提供扩展方法,如时区等。
- * 此类重写了父类的{@code toString()}方法,返回值为"yyyy-MM-dd HH:mm:ss"格式 + * 此类重写了父类的{@code toString()}方法,返回值为"yyyy-MM-dd HH:mm:ss"格式
+ * 相对于{@link Date},此类定义了时区,用于标识日期所在时区,默认为当前时区 + * * * @author Looly */ @@ -79,7 +84,7 @@ public class DateTime extends Date { private int minimalDaysInFirstWeek; /** - * 转换时间戳为 DateTime + * 转换时间戳为 DateTime,默认时区 * * @param timeMillis 时间戳,毫秒数 * @return DateTime @@ -90,7 +95,7 @@ public class DateTime extends Date { } /** - * 转换JDK date为 DateTime + * 转换JDK date为 DateTime,如果传入为原生对象,使用默认时区 * * @param date JDK Date * @return DateTime @@ -103,7 +108,7 @@ public class DateTime extends Date { } /** - * 转换 {@link Calendar} 为 DateTime + * 转换 {@link Calendar} 为 DateTime,使用{@link Calendar}中指定的时区 * * @param calendar {@link Calendar} * @return DateTime @@ -181,7 +186,7 @@ public class DateTime extends Date { * @param calendar {@link Calendar},不能为{@code null} */ public DateTime(final Calendar calendar) { - this(calendar.getTime(), calendar.getTimeZone()); + this(calendar.getTimeInMillis(), calendar.getTimeZone()); this.setFirstDayOfWeek(Week.of(calendar.getFirstDayOfWeek())); } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/DateUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/DateUtil.java index 3d303b16e..6076ba73e 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/DateUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/DateUtil.java @@ -46,6 +46,7 @@ import java.util.stream.Collectors; public class DateUtil extends CalendarUtil { // region ----- date + /** * 当前时间,转换为{@link DateTime}对象 * @@ -801,7 +802,9 @@ public class DateUtil extends CalendarUtil { } /** - * 将日期字符串转换为{@link DateTime}对象,格式:
+ * 将日期字符串转换为{@link DateTime}对象,在转换过程中,如果字符串中有时区信息,表示是指定时区的时间
+ * 此时此方法会将时区转换为当前时区,时间戳会根据时区变化。
+ * 支持格式:
*
    *
  1. yyyy-MM-dd HH:mm:ss
  2. *
  3. yyyy/MM/dd HH:mm:ss
  4. @@ -830,7 +833,7 @@ public class DateUtil extends CalendarUtil { * @return 日期 */ public static DateTime parse(final CharSequence dateCharSequence) { - if(TimeParser.INSTANCE.test(dateCharSequence)){ + if (TimeParser.INSTANCE.test(dateCharSequence)) { // 独立解析时间,则默认使用今天的日期 return TimeParser.INSTANCE.parse(dateCharSequence); } @@ -1709,6 +1712,7 @@ public class DateUtil extends CalendarUtil { } // region ----- range + /** * 创建日期范围生成器 * @@ -2071,70 +2075,4 @@ public class DateUtil extends CalendarUtil { public static int getLastDayOfMonth(final Date date) { return date(date).getLastDayOfMonth(); } - - // ------------------------------------------------------------------------ Private method start - - /** - * 标准化日期,默认处理以空格区分的日期时间格式,空格前为日期,空格后为时间:
    - * 将以下字符替换为"-" - * - *
    -	 * "."
    -	 * "/"
    -	 * "年"
    -	 * "月"
    -	 * 
    - *

    - * 将以下字符去除 - * - *

    -	 * "日"
    -	 * 
    - *

    - * 将以下字符替换为":" - * - *

    -	 * "时"
    -	 * "分"
    -	 * "秒"
    -	 * 
    - *

    - * 当末位是":"时去除之(不存在毫秒时) - * - * @param dateStr 日期时间字符串 - * @return 格式化后的日期字符串 - */ - private static String normalize(final CharSequence dateStr) { - if (StrUtil.isBlank(dateStr)) { - return StrUtil.str(dateStr); - } - - // 日期时间分开处理 - final List dateAndTime = SplitUtil.splitTrim(dateStr, StrUtil.SPACE); - final int size = dateAndTime.size(); - if (size < 1 || size > 2) { - // 非可被标准处理的格式 - return StrUtil.str(dateStr); - } - - final StringBuilder builder = StrUtil.builder(); - - // 日期部分("\"、"/"、"."、"年"、"月"都替换为"-") - String datePart = dateAndTime.get(0).replaceAll("[/.年月]", "-"); - datePart = StrUtil.removeSuffix(datePart, "日"); - builder.append(datePart); - - // 时间部分 - if (size == 2) { - builder.append(' '); - String timePart = dateAndTime.get(1).replaceAll("[时分秒]", ":"); - timePart = StrUtil.removeSuffix(timePart, ":"); - //将ISO8601中的逗号替换为. - timePart = timePart.replace(',', '.'); - builder.append(timePart); - } - - return builder.toString(); - } - // ------------------------------------------------------------------------ Private method end } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/Month.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/Month.java index e6cbda417..79204840e 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/Month.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/Month.java @@ -187,7 +187,7 @@ public enum Month { * @since 5.8.0 */ public static Month of(final String name) throws IllegalArgumentException { - if (null != name && name.length() > 2) { + if (null != name && name.length() > 1) { switch (Character.toLowerCase(name.charAt(0))) { case 'a': switch (Character.toLowerCase(name.charAt(1))) { @@ -226,6 +226,32 @@ public enum Month { return NOVEMBER; // november case 'd': return DECEMBER; // december + case '一': + return JANUARY; + case '二': + return FEBRUARY; + case '三': + return MARCH; + case '四': + return APRIL; + case '五': + return MAY; + case '六': + return JUNE; + case '七': + return JULY; + case '八': + return AUGUST; + case '九': + return SEPTEMBER; + case '十': + switch (Character.toLowerCase(name.charAt(1))){ + case '一': + return NOVEMBER; + case '二': + return DECEMBER; + } + return OCTOBER; } } @@ -234,11 +260,12 @@ public enum Month { /** * {@link java.time.Month}转换为Month对象 + * * @param month {@link java.time.Month} * @return Month * @since 5.8.0 */ - public static Month of(final java.time.Month month){ + public static Month of(final java.time.Month month) { return of(month.ordinal()); } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/TimeUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/TimeUtil.java index 3819688dd..7aef58fd5 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/TimeUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/TimeUtil.java @@ -28,7 +28,11 @@ import java.util.TimeZone; import java.util.function.Function; /** - * JDK8+中的{@link java.time} 工具类封装 + * JDK8+中的{@link java.time} 工具类封装
    + * + *

    * * @author looly * @see DateUtil java7及其以下版本,使用Date工具类 @@ -55,7 +59,8 @@ public class TimeUtil extends TemporalAccessorUtil { } /** - * {@link Instant}转{@link LocalDateTime},使用UTC时区 + * {@link Instant}转{@link LocalDateTime},使用UTC时区
    + * 此方法自动将一个UTC时间转换为本地时间,如传入00:00,则结果为08:00 * * @param instant {@link Instant} * @return {@link LocalDateTime} @@ -65,10 +70,12 @@ public class TimeUtil extends TemporalAccessorUtil { } /** - * {@link Instant}转{@link LocalDateTime} + * {@link Instant}转{@link LocalDateTime}
    + * instant是一个无时区的时间戳,在转换为本地时间时,需指定这个时间戳所在时区
    + * 如果所在时区与当前时区不同,会转换时间 * * @param instant {@link Instant} - * @param zoneId 时区 + * @param zoneId 时区,如果给定的时区与当前时区不同,会转换时间 * @return {@link LocalDateTime} */ public static LocalDateTime of(final Instant instant, final ZoneId zoneId) { @@ -80,10 +87,12 @@ public class TimeUtil extends TemporalAccessorUtil { } /** - * {@link Instant}转{@link LocalDateTime} + * {@link Instant}转{@link LocalDateTime}
    + * instant是一个无时区的时间戳,在转换为本地时间时,需指定这个时间戳所在时区
    + * 如果所在时区与当前时区不同,会转换时间 * * @param instant {@link Instant} - * @param timeZone 时区 + * @param timeZone 时区,如果给定的时区与当前时区不同,会转换时间 * @return {@link LocalDateTime} */ public static LocalDateTime of(final Instant instant, final TimeZone timeZone) { @@ -139,7 +148,8 @@ public class TimeUtil extends TemporalAccessorUtil { } /** - * {@link Date}转{@link LocalDateTime},使用默认时区 + * {@link Date}转{@link LocalDateTime},使用默认时区
    + * 如果为{@link DateTime}且提供了时区信息,则按照给定的时区转换为默认时区 * * @param date Date对象 * @return {@link LocalDateTime} diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/ZoneUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/ZoneUtil.java index 68135bd5d..d49220779 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/ZoneUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/ZoneUtil.java @@ -13,6 +13,7 @@ package org.dromara.hutool.core.date; import org.dromara.hutool.core.array.ArrayUtil; +import org.dromara.hutool.core.util.ObjUtil; import java.time.ZoneId; import java.util.TimeZone; @@ -80,10 +81,11 @@ public class ZoneUtil { * * @param rawOffset 偏移量 * @param timeUnit 偏移量单位 - * @return 时区ID + * @return 时区ID,未找到返回{@link null} */ public static String getAvailableID(final int rawOffset, final TimeUnit timeUnit) { - final String[] availableIDs = TimeZone.getAvailableIDs((int) timeUnit.toMillis(rawOffset)); + final String[] availableIDs = TimeZone.getAvailableIDs( + (int) ObjUtil.defaultIfNull(timeUnit, TimeUnit.MILLISECONDS).toMillis(rawOffset)); return ArrayUtil.isEmpty(availableIDs) ? null : availableIDs[0]; } } diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/GlobalRegexDateParser.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/GlobalRegexDateParser.java index 2c4ae3f42..cf67e340c 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/GlobalRegexDateParser.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/GlobalRegexDateParser.java @@ -31,12 +31,12 @@ public class GlobalRegexDateParser { final String yearRegex = "(?\\d{2,4})"; // 月的正则,匹配:Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec, // 或 January, February, March, April, May, June, July, August, September, October, November, December - final String monthRegex = "(?[jfmaasond][aepucoe][nbrylgptvc]\\w{0,6})"; + final String monthRegex = "(?[jfmaasond][aepucoe][nbrylgptvc]\\w{0,6}|[一二三四五六七八九十]{1,2}月)"; final String dayRegex = "(?\\d{1,2})(?:th)?"; // 周的正则,匹配:Mon, Tue, Wed, Thu, Fri, Sat, Sun, // 或 Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday // 周一般出现在日期头部,可选 - final String weekRegexWithSuff = "(?[mwfts][oeruha][ndieut](\\w{3,6})?\\W+)?"; + final String weekRegexWithSuff = "((?[mwfts][oeruha][ndieut](\\w{3,6})?|(星期|周)[一二三四五六日])\\W+)?"; // hh:mm:ss.SSSSZ hh:mm:ss.SSSS hh:mm:ss hh:mm final String timeRegexWithPre = "(" + "(\\W+|T)(at\\s)?(?\\d{1,2})" + diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/RegexDateParser.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/RegexDateParser.java index fd34a16d2..978e504bd 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/RegexDateParser.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/format/parser/RegexDateParser.java @@ -25,6 +25,8 @@ import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.text.dfa.WordTree; import java.io.Serializable; +import java.time.LocalDateTime; +import java.time.OffsetDateTime; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -115,7 +117,31 @@ public class RegexDateParser implements DateParser, Serializable { @Override public Date parse(final CharSequence source) throws DateException { Assert.notBlank(source, "Date str must be not blank!"); - return parseToBuilder(source).toDateTime(); + return parseToBuilder(source).toDate(); + } + + /** + * 解析日期,结果为{@link LocalDateTime} + * + * @param source 日期字符串 + * @return {@link LocalDateTime} + * @throws DateException 解析异常 + */ + public LocalDateTime parseToLocalDateTime(final CharSequence source) throws DateException { + Assert.notBlank(source, "Date str must be not blank!"); + return parseToBuilder(source).toLocalDateTime(); + } + + /** + * 解析日期,结果为{@link OffsetDateTime} + * + * @param source 日期字符串 + * @return {@link OffsetDateTime} + * @throws DateException 解析异常 + */ + public OffsetDateTime parseToOffsetDateTime(final CharSequence source) throws DateException { + Assert.notBlank(source, "Date str must be not blank!"); + return parseToBuilder(source).toOffsetDateTime(); } /** diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/date/CalendarUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/date/CalendarUtilTest.java index d335bbdda..97072f40b 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/date/CalendarUtilTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/date/CalendarUtilTest.java @@ -12,6 +12,7 @@ package org.dromara.hutool.core.date; +import org.dromara.hutool.core.lang.Console; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -40,4 +41,16 @@ public class CalendarUtilTest { DateUtil.date(calendar); }); } + + @Test + void setTimeZoneTest() { + // Calendar中,设置时区并不会变化时间戳 + final Calendar instance = Calendar.getInstance(); + Console.log(instance.getTimeInMillis()); + final long timeInMillis = instance.getTimeInMillis(); + instance.setTimeZone(ZoneUtil.ZONE_UTC); + final long timeInMillis2 = instance.getTimeInMillis(); + + Assertions.assertEquals(timeInMillis, timeInMillis2); + } } diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/date/DateBuilderTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/date/DateBuilderTest.java index 480d96b74..3d3ec3d23 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/date/DateBuilderTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/date/DateBuilderTest.java @@ -16,7 +16,7 @@ public class DateBuilderTest { builder.setDay(1); final Date date = builder.toDate(); - Assertions.assertEquals("2019-10-01", DateUtil.date(date).toDateStr()); + Assertions.assertEquals("2019-10-01 00:00:00", date.toString()); } @Test @@ -32,7 +32,7 @@ public class DateBuilderTest { .setZone(TimeZone.getDefault()); final LocalDateTime dateTime = builder.toLocalDateTime(); - Assertions.assertEquals("2019-10-01T10:20:30.900", builder.toLocalDateTime().toString()); + Assertions.assertEquals("2019-10-01T10:20:30.900", dateTime.toString()); } @Test diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/date/DateTimeTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/date/DateTimeTest.java index 047137ced..8243e1e5f 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/date/DateTimeTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/date/DateTimeTest.java @@ -15,6 +15,8 @@ package org.dromara.hutool.core.date; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import java.util.TimeZone; + /** * DateTime单元测试 * @@ -128,6 +130,17 @@ public class DateTimeTest { Assertions.assertEquals("2017-01-05T12:34:23+08:00", dateStr); } + @Test + public void toStringWithTimeZoneTest() { + final DateTime dateTime = new DateTime("2017-01-05 12:34:23", DatePattern.NORM_DATETIME_FORMAT); + + final String dateStr = dateTime.toString(TimeZone.getTimeZone("UTC")); + Assertions.assertEquals("2017-01-05 04:34:23", dateStr); + + dateTime.setTimeZone(TimeZone.getTimeZone("UTC")); + Assertions.assertEquals("2017-01-05 04:34:23", dateTime.toString()); + } + @Test public void monthTest() { //noinspection ConstantConditions @@ -138,7 +151,7 @@ public class DateTimeTest { @Test public void weekOfYearTest() { final DateTime date = DateUtil.date(DateUtil.parse("2016-12-27")); - //noinspection ConstantConditions + Assertions.assertEquals(2016, date.year()); //跨年的周返回的总是1 Assertions.assertEquals(1, date.weekOfYear()); diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/date/IssueI9C2D4Test.java b/hutool-core/src/test/java/org/dromara/hutool/core/date/IssueI9C2D4Test.java index e0d4c647e..41ed6f5cf 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/date/IssueI9C2D4Test.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/date/IssueI9C2D4Test.java @@ -18,7 +18,7 @@ public class IssueI9C2D4Test { public void parseHttpTest2() { final String dateStr = "星期四, 28 三月 2024 14:33:49 GMT"; final Date parse = DateUtil.parse(dateStr); - Assertions.assertEquals("2024-03-28 14:33:49", Objects.requireNonNull(parse).toString()); + Assertions.assertEquals("2024-03-28 22:33:49", Objects.requireNonNull(parse).toString()); } @Test diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/date/MonthTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/date/MonthTest.java index ad1e423ce..49466dd35 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/date/MonthTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/date/MonthTest.java @@ -77,5 +77,14 @@ public class MonthTest { month = Month.of(java.time.Month.FEBRUARY); Assertions.assertEquals(Month.FEBRUARY, month); + + month = Month.of("二月"); + Assertions.assertEquals(Month.FEBRUARY, month); + month = Month.of("十月"); + Assertions.assertEquals(Month.OCTOBER, month); + month = Month.of("十一月"); + Assertions.assertEquals(Month.NOVEMBER, month); + month = Month.of("十二月"); + Assertions.assertEquals(Month.DECEMBER, month); } } diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/date/TimeUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/date/TimeUtilTest.java index d1545447f..c1db57210 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/date/TimeUtilTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/date/TimeUtilTest.java @@ -19,7 +19,6 @@ import org.junit.jupiter.api.Test; import java.time.*; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; -import java.util.Date; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; @@ -37,7 +36,8 @@ public class TimeUtilTest { @Test public void ofTest() { final String dateStr = "2020-01-23T12:23:56"; - final Date dt = DateUtil.parse(dateStr); + final DateTime dt = DateUtil.parse(dateStr); + Console.log(dt.getTimeZone()); final LocalDateTime of = TimeUtil.of(dt); Assertions.assertNotNull(of); @@ -47,9 +47,10 @@ public class TimeUtilTest { @Test public void ofUTCTest() { final String dateStr = "2020-01-23T12:23:56Z"; - final Date dt = DateUtil.parse(dateStr); + // 因为`Z`位于末尾,表示为UTC时间,parse后会自动转换为本地时间 + final DateTime dt = DateUtil.parse(dateStr); - final LocalDateTime of = TimeUtil.of(dt); + final LocalDateTime of = TimeUtil.of(dt.setTimeZone(ZoneUtil.ZONE_UTC)); final LocalDateTime of2 = TimeUtil.ofUTC(dt.getTime()); Assertions.assertNotNull(of); Assertions.assertNotNull(of2); diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/date/ZoneUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/date/ZoneUtilTest.java index 9d43dd5c9..9d21ff6f5 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/date/ZoneUtilTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/date/ZoneUtilTest.java @@ -19,7 +19,8 @@ import java.time.ZoneId; import java.util.TimeZone; import java.util.concurrent.TimeUnit; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; public class ZoneUtilTest { @@ -55,21 +56,6 @@ public class ZoneUtilTest { assertNull(result, "Expected null TimeZone for invalid offset"); } - @Test - public void testGetTimeZoneByOffsetWithNullTimeUnitThrowsException() { - // Arrange - final int rawOffset = 8; - final TimeUnit timeUnit = null; // Null unit to simulate error condition - - // Act & Assert - final NullPointerException thrown = assertThrows( - NullPointerException.class, - () -> ZoneUtil.getTimeZoneByOffset(rawOffset, timeUnit), - "Expected NullPointerException for null TimeUnit" - ); - assertTrue(thrown.getMessage().contains("timeUnit"), "Exception message should mention the null parameter"); - } - @Test public void testGetAvailableIDWithInvalidOffset() { // Test with an invalid offset that should result in null or an exception. diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/date/format/parser/GlobalRegexDateParserTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/date/format/parser/GlobalRegexDateParserTest.java index d288f3050..2100bcb3e 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/date/format/parser/GlobalRegexDateParserTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/date/format/parser/GlobalRegexDateParserTest.java @@ -63,6 +63,8 @@ public class GlobalRegexDateParserTest { assertParse("2014-04-08 00:00:00", "2014年04月08日"); assertParse("2017-02-01 12:23:45", "2017年02月01日 12时23分45秒"); assertParse("2017-02-01 12:23:45", "2017年02月01日 12:23:45"); + assertParse("2024-03-28 22:33:49", "星期四, 28 三月 2024 14:33:49 GMT"); + assertParse("2024-03-28 22:33:49", "周四, 28 三月 2024 14:33:49 GMT"); } @Test