This commit is contained in:
Looly 2023-02-09 20:59:26 +08:00
parent 9c72e216ef
commit 5753444de2
2 changed files with 47 additions and 0 deletions

View File

@ -25,6 +25,9 @@ import cn.hutool.core.util.CharUtil;
public class UTCDateParser extends DefaultDateBasic implements DateParser {
private static final long serialVersionUID = 1L;
/**
* 单例对象
*/
public static UTCDateParser INSTANCE = new UTCDateParser();
@Override
@ -57,6 +60,7 @@ public class UTCDateParser extends DefaultDateBasic implements DateParser {
if (StrUtil.contains(source, CharUtil.DOT)) {
// 带毫秒格式类似2018-09-13T05:34:31.999+08:00
source = normalizeMillSeconds(source, ".", "+");
return new DateTime(source, DatePattern.UTC_MS_WITH_XXX_OFFSET_FORMAT);
} else {
// 格式类似2018-09-13T05:34:31+08:00
@ -73,6 +77,7 @@ public class UTCDateParser extends DefaultDateBasic implements DateParser {
if (StrUtil.contains(source, CharUtil.DOT)) {
// 带毫秒格式类似2018-09-13T05:34:31.999-08:00
source = normalizeMillSeconds(source, ".", "-");
return new DateTime(source, DatePattern.UTC_MS_WITH_XXX_OFFSET_FORMAT);
} else {
// 格式类似2018-09-13T05:34:31-08:00
@ -87,10 +92,31 @@ public class UTCDateParser extends DefaultDateBasic implements DateParser {
return new DateTime(source + ":00", DatePattern.UTC_SIMPLE_FORMAT);
} else if (StrUtil.contains(source, CharUtil.DOT)) {
// 可能为 2021-03-17T06:31:33.99
source = normalizeMillSeconds(source, ".", null);
return new DateTime(source, DatePattern.UTC_SIMPLE_MS_FORMAT);
}
}
// 没有更多匹配的时间格式
throw new DateException("No UTC format fit for date String [{}] !", source);
}
/**
* 如果日期中的毫秒部分超出3位会导致秒数增加因此只保留前三位<br>
* issue#2887
*
* @param dateStr 日期字符串
* @param before 毫秒部分的前一个字符
* @param after 毫秒部分的后一个字符
* @return 规范之后的毫秒部分
*/
private static String normalizeMillSeconds(final String dateStr, final CharSequence before, final CharSequence after) {
if (StrUtil.isBlank(after)) {
final String millOrNaco = StrUtil.subPre(StrUtil.subAfter(dateStr, before, true), 3);
return StrUtil.subBefore(dateStr, before, true) + before + millOrNaco;
}
final String millOrNaco = StrUtil.subPre(StrUtil.subBetween(dateStr, before, after), 3);
return StrUtil.subBefore(dateStr, before, true)
+ before
+ millOrNaco + after + StrUtil.subAfter(dateStr, after, true);
}
}

View File

@ -1079,4 +1079,25 @@ public class DateUtilTest {
Assert.assertEquals(dayOfMonth, Objects.requireNonNull(dateTime).dayOfMonth());
Assert.assertTrue("not is last day of this month !!",DateUtil.isLastDayOfMonth(dateTime));
}
/**
* issue#2887 由于UTC时间的毫秒部分超出3位导致的秒数增加的问题
*/
@Test
public void parseUTCTest4() {
final String dateStr = "2023-02-07T00:02:16.12345+08:00";
final DateTime dateTime = DateUtil.parse(dateStr);
Assert.assertNotNull(dateTime);
Assert.assertEquals("2023-02-07 00:02:16", dateTime.toString());
final String dateStr2 = "2023-02-07T00:02:16.12345-08:00";
final DateTime dateTime2 = DateUtil.parse(dateStr2);
Assert.assertNotNull(dateTime2);
Assert.assertEquals("2023-02-07 00:02:16", dateTime2.toString());
final String dateStr3 = "2021-03-17T06:31:33.9999";
final DateTime dateTime3 = DateUtil.parse(dateStr3);
Assert.assertNotNull(dateTime3);
Assert.assertEquals("2021-03-17 06:31:33", dateTime3.toString());
}
}