DateUtil.parseUTC方法标记废弃,改名为parseISO8601(issue#IBB6I5@Gitee)

This commit is contained in:
Looly 2024-12-15 22:23:41 +08:00
parent 51bc90bd0d
commit 8a8a5f7161
5 changed files with 102 additions and 43 deletions

View File

@ -2,13 +2,14 @@
# 🚀Changelog
-------------------------------------------------------------------------------------------------------------
# 5.8.35(2024-12-08)
# 5.8.35(2024-12-15)
### 🐣新特性
* 【poi 】 优化ExcelWriter中使用比较器writer的方法只对第一条数据进行排序pr#3807@Github
* 【extra 】 优化Ftp.download返回false抛出异常issue#3805@Github
* 【core 】 优化MAC地址正则issue#IB95X4@Gitee
* 【json 】 JSON的getByPath方法新增更为通用的指定出参类型重载pr#3814@Github
* 【core 】 DateUtil.parseUTC方法标记废弃改名为parseISO8601issue#IBB6I5@Gitee
### 🐞Bug修复
* 【crypto 】 修复JWTSignerUtil.createSigner中algorithmId未转换问题issue#3806@Github

View File

@ -844,16 +844,37 @@ public class DateUtil extends CalendarUtil {
* @param utcString UTC时间
* @return 日期对象
* @since 4.1.14
* @deprecated 方法歧义带T的日期并不一定是UTC时间请使用 {@link #parseISO8601(String)}
*/
@Deprecated
public static DateTime parseUTC(String utcString) {
if (utcString == null) {
return parseISO8601(utcString);
}
/**
* 解析ISO8601时间格式<br>
* <ol>
* <li>yyyy-MM-dd'T'HH:mm:ss'Z'</li>
* <li>yyyy-MM-dd'T'HH:mm:ss.SSS'Z'</li>
* <li>yyyy-MM-dd'T'HH:mm:ssZ</li>
* <li>yyyy-MM-dd'T'HH:mm:ss.SSSZ</li>
* <li>yyyy-MM-dd'T'HH:mm:ss+0800</li>
* <li>yyyy-MM-dd'T'HH:mm:ss+08:00</li>
* </ol>
*
* @param iso8601String ISO8601时间
* @return 日期对象
* @since 5.8.34
*/
public static DateTime parseISO8601(String iso8601String) {
if (iso8601String == null) {
return null;
}
final int length = utcString.length();
if (StrUtil.contains(utcString, 'Z')) {
final int length = iso8601String.length();
if (StrUtil.contains(iso8601String, 'Z')) {
if (length == DatePattern.UTC_PATTERN.length() - 4) {
// 格式类似2018-09-13T05:34:31Z-4表示减去4个单引号的长度
return parse(utcString, DatePattern.UTC_FORMAT);
return parse(iso8601String, DatePattern.UTC_FORMAT);
}
final int patternLength = DatePattern.UTC_MS_PATTERN.length();
@ -861,61 +882,61 @@ public class DateUtil extends CalendarUtil {
// -4 ~ -6范围表示匹配毫秒1~3位的情况
if (length <= patternLength && length >= patternLength - 6) {
// issue#I7H34N支持最多6位毫秒
return parse(utcString, DatePattern.UTC_MS_FORMAT);
return parse(iso8601String, DatePattern.UTC_MS_FORMAT);
}
} else if (StrUtil.contains(utcString, '+')) {
} else if (StrUtil.contains(iso8601String, '+')) {
// 去除类似2019-06-01T19:45:43 +08:00加号前的空格
utcString = utcString.replace(" +", "+");
final String zoneOffset = StrUtil.subAfter(utcString, '+', true);
iso8601String = iso8601String.replace(" +", "+");
final String zoneOffset = StrUtil.subAfter(iso8601String, '+', true);
if (StrUtil.isBlank(zoneOffset)) {
throw new DateException("Invalid format: [{}]", utcString);
throw new DateException("Invalid format: [{}]", iso8601String);
}
if (false == StrUtil.contains(zoneOffset, ':')) {
// +0800转换为+08:00
final String pre = StrUtil.subBefore(utcString, '+', true);
utcString = pre + "+" + zoneOffset.substring(0, 2) + ":" + "00";
final String pre = StrUtil.subBefore(iso8601String, '+', true);
iso8601String = pre + "+" + zoneOffset.substring(0, 2) + ":" + "00";
}
if (StrUtil.contains(utcString, CharUtil.DOT)) {
if (StrUtil.contains(iso8601String, CharUtil.DOT)) {
// 带毫秒格式类似2018-09-13T05:34:31.999+08:00
utcString = normalizeMillSeconds(utcString, ".", "+");
return parse(utcString, DatePattern.UTC_MS_WITH_XXX_OFFSET_FORMAT);
iso8601String = normalizeMillSeconds(iso8601String, ".", "+");
return parse(iso8601String, DatePattern.UTC_MS_WITH_XXX_OFFSET_FORMAT);
} else {
// 格式类似2018-09-13T05:34:31+08:00
return parse(utcString, DatePattern.UTC_WITH_XXX_OFFSET_FORMAT);
return parse(iso8601String, DatePattern.UTC_WITH_XXX_OFFSET_FORMAT);
}
} else if(ReUtil.contains("-\\d{2}:?00", utcString)){
} else if(ReUtil.contains("-\\d{2}:?00", iso8601String)){
// Issue#2612类似 2022-09-14T23:59:00-08:00 或者 2022-09-14T23:59:00-0800
// 去除类似2019-06-01T19:45:43 -08:00加号前的空格
utcString = utcString.replace(" -", "-");
if(':' != utcString.charAt(utcString.length() - 3)){
utcString = utcString.substring(0, utcString.length() - 2) + ":00";
iso8601String = iso8601String.replace(" -", "-");
if(':' != iso8601String.charAt(iso8601String.length() - 3)){
iso8601String = iso8601String.substring(0, iso8601String.length() - 2) + ":00";
}
if (StrUtil.contains(utcString, CharUtil.DOT)) {
if (StrUtil.contains(iso8601String, CharUtil.DOT)) {
// 带毫秒格式类似2018-09-13T05:34:31.999-08:00
utcString = normalizeMillSeconds(utcString, ".", "-");
return new DateTime(utcString, DatePattern.UTC_MS_WITH_XXX_OFFSET_FORMAT);
iso8601String = normalizeMillSeconds(iso8601String, ".", "-");
return new DateTime(iso8601String, DatePattern.UTC_MS_WITH_XXX_OFFSET_FORMAT);
} else {
// 格式类似2018-09-13T05:34:31-08:00
return new DateTime(utcString, DatePattern.UTC_WITH_XXX_OFFSET_FORMAT);
return new DateTime(iso8601String, DatePattern.UTC_WITH_XXX_OFFSET_FORMAT);
}
} else {
if (length == DatePattern.UTC_SIMPLE_PATTERN.length() - 2) {
// 格式类似2018-09-13T05:34:31
return parse(utcString, DatePattern.UTC_SIMPLE_FORMAT);
return parse(iso8601String, DatePattern.UTC_SIMPLE_FORMAT);
} else if (length == DatePattern.UTC_SIMPLE_PATTERN.length() - 5) {
// 格式类似2018-09-13T05:34
return parse(utcString + ":00", DatePattern.UTC_SIMPLE_FORMAT);
} else if (StrUtil.contains(utcString, CharUtil.DOT)) {
return parse(iso8601String + ":00", DatePattern.UTC_SIMPLE_FORMAT);
} else if (StrUtil.contains(iso8601String, CharUtil.DOT)) {
// 可能为 2021-03-17T06:31:33.99
utcString = normalizeMillSeconds(utcString, ".", null);
return parse(utcString, DatePattern.UTC_SIMPLE_MS_FORMAT);
iso8601String = normalizeMillSeconds(iso8601String, ".", null);
return parse(iso8601String, DatePattern.UTC_SIMPLE_MS_FORMAT);
}
}
// 没有更多匹配的时间格式
throw new DateException("No format fit for date String [{}] !", utcString);
throw new DateException("No format fit for date String [{}] !", iso8601String);
}
/**
@ -1025,8 +1046,8 @@ public class DateUtil extends CalendarUtil {
// Wed Aug 01 00:00:00 CST 2012
return parseRFC2822(dateStr);
} else if (StrUtil.contains(dateStr, 'T')) {
// UTC时间
return parseUTC(dateStr);
// ISO8601时间
return parseISO8601(dateStr);
}
//标准日期格式包括单个数字的日期时间

View File

@ -605,9 +605,9 @@ public class DateUtilTest {
}
@Test
public void parseUTCTest() {
public void parseISO8601Test() {
String dateStr1 = "2018-09-13T05:34:31Z";
DateTime dt = DateUtil.parseUTC(dateStr1);
DateTime dt = DateUtil.parseISO8601(dateStr1);
// parse方法支持UTC格式测试
final DateTime dt2 = DateUtil.parse(dateStr1);
@ -622,12 +622,12 @@ public class DateUtilTest {
assertEquals("2018-09-13 13:34:31", dateStr);
dateStr1 = "2018-09-13T13:34:32+0800";
dt = DateUtil.parseUTC(dateStr1);
dt = DateUtil.parseISO8601(dateStr1);
dateStr = dt.toString(TimeZone.getTimeZone("GMT+8:00"));
assertEquals("2018-09-13 13:34:32", dateStr);
dateStr1 = "2018-09-13T13:34:33+08:00";
dt = DateUtil.parseUTC(dateStr1);
dt = DateUtil.parseISO8601(dateStr1);
dateStr = dt.toString(TimeZone.getTimeZone("GMT+8:00"));
assertEquals("2018-09-13 13:34:33", dateStr);
@ -644,14 +644,14 @@ public class DateUtilTest {
assertEquals("2018-09-13 13:34:35", dateStr);
dateStr1 = "2018-09-13T13:34:36.999+0800";
dt = DateUtil.parseUTC(dateStr1);
dt = DateUtil.parseISO8601(dateStr1);
final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DatePattern.NORM_DATETIME_MS_PATTERN);
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
dateStr = dt.toString(simpleDateFormat);
assertEquals("2018-09-13 13:34:36.999", dateStr);
dateStr1 = "2018-09-13T13:34:37.999+08:00";
dt = DateUtil.parseUTC(dateStr1);
dt = DateUtil.parseISO8601(dateStr1);
dateStr = dt.toString(simpleDateFormat);
assertEquals("2018-09-13 13:34:37.999", dateStr);
@ -676,19 +676,19 @@ public class DateUtilTest {
}
@Test
public void parseUTCTest2() {
public void parseUTCTest() {
// issue1503@Github
// 检查不同毫秒长度都可以正常匹配
String utcTime = "2021-03-30T12:56:51.3Z";
DateTime parse = DateUtil.parseUTC(utcTime);
DateTime parse = DateUtil.parseISO8601(utcTime);
assertEquals("2021-03-30 12:56:51", parse.toString());
utcTime = "2021-03-30T12:56:51.34Z";
parse = DateUtil.parseUTC(utcTime);
parse = DateUtil.parseISO8601(utcTime);
assertEquals("2021-03-30 12:56:51", parse.toString());
utcTime = "2021-03-30T12:56:51.345Z";
parse = DateUtil.parseUTC(utcTime);
parse = DateUtil.parseISO8601(utcTime);
assertEquals("2021-03-30 12:56:51", parse.toString());
}
@ -994,7 +994,7 @@ public class DateUtilTest {
@SuppressWarnings("ConstantConditions")
@Test
public void parseISO8601Test() {
public void parseWithMilsTest() {
final String dt = "2020-06-03 12:32:12,333";
final DateTime parse = DateUtil.parse(dt);
assertEquals("2020-06-03 12:32:12", parse.toString());

View File

@ -0,0 +1,12 @@
package cn.hutool.core.date;
import org.junit.jupiter.api.Test;
import java.text.SimpleDateFormat;
public class IssueIB9NPUTest {
@Test
void parseTest() {
DateUtil.parse("202409032400", new SimpleDateFormat("yyyyMMddHHmm"));
}
}

View File

@ -0,0 +1,25 @@
package cn.hutool.core.date;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.time.ZoneId;
import java.util.TimeZone;
public class IssueIBB6I5Test {
@Test
void parseISO8601Test() {
DateTime date = DateUtil.parseISO8601("2024-12-13T08:02:27Z");
TimeZone timeZone = TimeZone.getTimeZone(ZoneId.of("Asia/Shanghai"));
date.setTimeZone(timeZone);
Assertions.assertEquals("2024-12-13 16:02:27", date.toString());
}
@Test
void parseISO8601Test2() {
DateTime date = DateUtil.parseISO8601("2024-12-13T08:02:27");
TimeZone timeZone = TimeZone.getTimeZone(ZoneId.of("Asia/Shanghai"));
date.setTimeZone(timeZone);
Assertions.assertEquals("2024-12-13 08:02:27", date.toString());
}
}