mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
DateUtil.parseUTC方法标记废弃,改名为parseISO8601(issue#IBB6I5@Gitee)
This commit is contained in:
parent
51bc90bd0d
commit
8a8a5f7161
@ -2,13 +2,14 @@
|
|||||||
# 🚀Changelog
|
# 🚀Changelog
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------
|
||||||
# 5.8.35(2024-12-08)
|
# 5.8.35(2024-12-15)
|
||||||
|
|
||||||
### 🐣新特性
|
### 🐣新特性
|
||||||
* 【poi 】 优化ExcelWriter中使用比较器writer的方法,只对第一条数据进行排序(pr#3807@Github)
|
* 【poi 】 优化ExcelWriter中使用比较器writer的方法,只对第一条数据进行排序(pr#3807@Github)
|
||||||
* 【extra 】 优化Ftp.download,返回false抛出异常(issue#3805@Github)
|
* 【extra 】 优化Ftp.download,返回false抛出异常(issue#3805@Github)
|
||||||
* 【core 】 优化MAC地址正则(issue#IB95X4@Gitee)
|
* 【core 】 优化MAC地址正则(issue#IB95X4@Gitee)
|
||||||
* 【json 】 JSON的getByPath方法新增更为通用的指定出参类型重载(pr#3814@Github)
|
* 【json 】 JSON的getByPath方法新增更为通用的指定出参类型重载(pr#3814@Github)
|
||||||
|
* 【core 】 DateUtil.parseUTC方法标记废弃,改名为parseISO8601(issue#IBB6I5@Gitee)
|
||||||
|
|
||||||
### 🐞Bug修复
|
### 🐞Bug修复
|
||||||
* 【crypto 】 修复JWTSignerUtil.createSigner中algorithmId未转换问题(issue#3806@Github)
|
* 【crypto 】 修复JWTSignerUtil.createSigner中algorithmId未转换问题(issue#3806@Github)
|
||||||
|
@ -844,16 +844,37 @@ public class DateUtil extends CalendarUtil {
|
|||||||
* @param utcString UTC时间
|
* @param utcString UTC时间
|
||||||
* @return 日期对象
|
* @return 日期对象
|
||||||
* @since 4.1.14
|
* @since 4.1.14
|
||||||
|
* @deprecated 方法歧义,带T的日期并不一定是UTC时间,请使用 {@link #parseISO8601(String)}
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public static DateTime parseUTC(String utcString) {
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
final int length = utcString.length();
|
final int length = iso8601String.length();
|
||||||
if (StrUtil.contains(utcString, 'Z')) {
|
if (StrUtil.contains(iso8601String, 'Z')) {
|
||||||
if (length == DatePattern.UTC_PATTERN.length() - 4) {
|
if (length == DatePattern.UTC_PATTERN.length() - 4) {
|
||||||
// 格式类似:2018-09-13T05:34:31Z,-4表示减去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();
|
final int patternLength = DatePattern.UTC_MS_PATTERN.length();
|
||||||
@ -861,61 +882,61 @@ public class DateUtil extends CalendarUtil {
|
|||||||
// -4 ~ -6范围表示匹配毫秒1~3位的情况
|
// -4 ~ -6范围表示匹配毫秒1~3位的情况
|
||||||
if (length <= patternLength && length >= patternLength - 6) {
|
if (length <= patternLength && length >= patternLength - 6) {
|
||||||
// issue#I7H34N,支持最多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加号前的空格
|
// 去除类似2019-06-01T19:45:43 +08:00加号前的空格
|
||||||
utcString = utcString.replace(" +", "+");
|
iso8601String = iso8601String.replace(" +", "+");
|
||||||
final String zoneOffset = StrUtil.subAfter(utcString, '+', true);
|
final String zoneOffset = StrUtil.subAfter(iso8601String, '+', true);
|
||||||
if (StrUtil.isBlank(zoneOffset)) {
|
if (StrUtil.isBlank(zoneOffset)) {
|
||||||
throw new DateException("Invalid format: [{}]", utcString);
|
throw new DateException("Invalid format: [{}]", iso8601String);
|
||||||
}
|
}
|
||||||
if (false == StrUtil.contains(zoneOffset, ':')) {
|
if (false == StrUtil.contains(zoneOffset, ':')) {
|
||||||
// +0800转换为+08:00
|
// +0800转换为+08:00
|
||||||
final String pre = StrUtil.subBefore(utcString, '+', true);
|
final String pre = StrUtil.subBefore(iso8601String, '+', true);
|
||||||
utcString = pre + "+" + zoneOffset.substring(0, 2) + ":" + "00";
|
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
|
// 带毫秒,格式类似:2018-09-13T05:34:31.999+08:00
|
||||||
utcString = normalizeMillSeconds(utcString, ".", "+");
|
iso8601String = normalizeMillSeconds(iso8601String, ".", "+");
|
||||||
return parse(utcString, DatePattern.UTC_MS_WITH_XXX_OFFSET_FORMAT);
|
return parse(iso8601String, DatePattern.UTC_MS_WITH_XXX_OFFSET_FORMAT);
|
||||||
} else {
|
} else {
|
||||||
// 格式类似:2018-09-13T05:34:31+08:00
|
// 格式类似: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
|
// Issue#2612,类似 2022-09-14T23:59:00-08:00 或者 2022-09-14T23:59:00-0800
|
||||||
|
|
||||||
// 去除类似2019-06-01T19:45:43 -08:00加号前的空格
|
// 去除类似2019-06-01T19:45:43 -08:00加号前的空格
|
||||||
utcString = utcString.replace(" -", "-");
|
iso8601String = iso8601String.replace(" -", "-");
|
||||||
if(':' != utcString.charAt(utcString.length() - 3)){
|
if(':' != iso8601String.charAt(iso8601String.length() - 3)){
|
||||||
utcString = utcString.substring(0, utcString.length() - 2) + ":00";
|
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
|
// 带毫秒,格式类似:2018-09-13T05:34:31.999-08:00
|
||||||
utcString = normalizeMillSeconds(utcString, ".", "-");
|
iso8601String = normalizeMillSeconds(iso8601String, ".", "-");
|
||||||
return new DateTime(utcString, DatePattern.UTC_MS_WITH_XXX_OFFSET_FORMAT);
|
return new DateTime(iso8601String, DatePattern.UTC_MS_WITH_XXX_OFFSET_FORMAT);
|
||||||
} else {
|
} else {
|
||||||
// 格式类似:2018-09-13T05:34:31-08:00
|
// 格式类似: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 {
|
} else {
|
||||||
if (length == DatePattern.UTC_SIMPLE_PATTERN.length() - 2) {
|
if (length == DatePattern.UTC_SIMPLE_PATTERN.length() - 2) {
|
||||||
// 格式类似:2018-09-13T05:34:31
|
// 格式类似: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) {
|
} else if (length == DatePattern.UTC_SIMPLE_PATTERN.length() - 5) {
|
||||||
// 格式类似:2018-09-13T05:34
|
// 格式类似:2018-09-13T05:34
|
||||||
return parse(utcString + ":00", DatePattern.UTC_SIMPLE_FORMAT);
|
return parse(iso8601String + ":00", DatePattern.UTC_SIMPLE_FORMAT);
|
||||||
} else if (StrUtil.contains(utcString, CharUtil.DOT)) {
|
} else if (StrUtil.contains(iso8601String, CharUtil.DOT)) {
|
||||||
// 可能为: 2021-03-17T06:31:33.99
|
// 可能为: 2021-03-17T06:31:33.99
|
||||||
utcString = normalizeMillSeconds(utcString, ".", null);
|
iso8601String = normalizeMillSeconds(iso8601String, ".", null);
|
||||||
return parse(utcString, DatePattern.UTC_SIMPLE_MS_FORMAT);
|
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
|
// Wed Aug 01 00:00:00 CST 2012
|
||||||
return parseRFC2822(dateStr);
|
return parseRFC2822(dateStr);
|
||||||
} else if (StrUtil.contains(dateStr, 'T')) {
|
} else if (StrUtil.contains(dateStr, 'T')) {
|
||||||
// UTC时间
|
// ISO8601时间
|
||||||
return parseUTC(dateStr);
|
return parseISO8601(dateStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
//标准日期格式(包括单个数字的日期时间)
|
//标准日期格式(包括单个数字的日期时间)
|
||||||
|
@ -605,9 +605,9 @@ public class DateUtilTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void parseUTCTest() {
|
public void parseISO8601Test() {
|
||||||
String dateStr1 = "2018-09-13T05:34:31Z";
|
String dateStr1 = "2018-09-13T05:34:31Z";
|
||||||
DateTime dt = DateUtil.parseUTC(dateStr1);
|
DateTime dt = DateUtil.parseISO8601(dateStr1);
|
||||||
|
|
||||||
// parse方法支持UTC格式测试
|
// parse方法支持UTC格式测试
|
||||||
final DateTime dt2 = DateUtil.parse(dateStr1);
|
final DateTime dt2 = DateUtil.parse(dateStr1);
|
||||||
@ -622,12 +622,12 @@ public class DateUtilTest {
|
|||||||
assertEquals("2018-09-13 13:34:31", dateStr);
|
assertEquals("2018-09-13 13:34:31", dateStr);
|
||||||
|
|
||||||
dateStr1 = "2018-09-13T13:34:32+0800";
|
dateStr1 = "2018-09-13T13:34:32+0800";
|
||||||
dt = DateUtil.parseUTC(dateStr1);
|
dt = DateUtil.parseISO8601(dateStr1);
|
||||||
dateStr = dt.toString(TimeZone.getTimeZone("GMT+8:00"));
|
dateStr = dt.toString(TimeZone.getTimeZone("GMT+8:00"));
|
||||||
assertEquals("2018-09-13 13:34:32", dateStr);
|
assertEquals("2018-09-13 13:34:32", dateStr);
|
||||||
|
|
||||||
dateStr1 = "2018-09-13T13:34:33+08:00";
|
dateStr1 = "2018-09-13T13:34:33+08:00";
|
||||||
dt = DateUtil.parseUTC(dateStr1);
|
dt = DateUtil.parseISO8601(dateStr1);
|
||||||
dateStr = dt.toString(TimeZone.getTimeZone("GMT+8:00"));
|
dateStr = dt.toString(TimeZone.getTimeZone("GMT+8:00"));
|
||||||
assertEquals("2018-09-13 13:34:33", dateStr);
|
assertEquals("2018-09-13 13:34:33", dateStr);
|
||||||
|
|
||||||
@ -644,14 +644,14 @@ public class DateUtilTest {
|
|||||||
assertEquals("2018-09-13 13:34:35", dateStr);
|
assertEquals("2018-09-13 13:34:35", dateStr);
|
||||||
|
|
||||||
dateStr1 = "2018-09-13T13:34:36.999+0800";
|
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);
|
final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DatePattern.NORM_DATETIME_MS_PATTERN);
|
||||||
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
|
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
|
||||||
dateStr = dt.toString(simpleDateFormat);
|
dateStr = dt.toString(simpleDateFormat);
|
||||||
assertEquals("2018-09-13 13:34:36.999", dateStr);
|
assertEquals("2018-09-13 13:34:36.999", dateStr);
|
||||||
|
|
||||||
dateStr1 = "2018-09-13T13:34:37.999+08:00";
|
dateStr1 = "2018-09-13T13:34:37.999+08:00";
|
||||||
dt = DateUtil.parseUTC(dateStr1);
|
dt = DateUtil.parseISO8601(dateStr1);
|
||||||
dateStr = dt.toString(simpleDateFormat);
|
dateStr = dt.toString(simpleDateFormat);
|
||||||
assertEquals("2018-09-13 13:34:37.999", dateStr);
|
assertEquals("2018-09-13 13:34:37.999", dateStr);
|
||||||
|
|
||||||
@ -676,19 +676,19 @@ public class DateUtilTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void parseUTCTest2() {
|
public void parseUTCTest() {
|
||||||
// issue1503@Github
|
// issue1503@Github
|
||||||
// 检查不同毫秒长度都可以正常匹配
|
// 检查不同毫秒长度都可以正常匹配
|
||||||
String utcTime = "2021-03-30T12:56:51.3Z";
|
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());
|
assertEquals("2021-03-30 12:56:51", parse.toString());
|
||||||
|
|
||||||
utcTime = "2021-03-30T12:56:51.34Z";
|
utcTime = "2021-03-30T12:56:51.34Z";
|
||||||
parse = DateUtil.parseUTC(utcTime);
|
parse = DateUtil.parseISO8601(utcTime);
|
||||||
assertEquals("2021-03-30 12:56:51", parse.toString());
|
assertEquals("2021-03-30 12:56:51", parse.toString());
|
||||||
|
|
||||||
utcTime = "2021-03-30T12:56:51.345Z";
|
utcTime = "2021-03-30T12:56:51.345Z";
|
||||||
parse = DateUtil.parseUTC(utcTime);
|
parse = DateUtil.parseISO8601(utcTime);
|
||||||
assertEquals("2021-03-30 12:56:51", parse.toString());
|
assertEquals("2021-03-30 12:56:51", parse.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -994,7 +994,7 @@ public class DateUtilTest {
|
|||||||
|
|
||||||
@SuppressWarnings("ConstantConditions")
|
@SuppressWarnings("ConstantConditions")
|
||||||
@Test
|
@Test
|
||||||
public void parseISO8601Test() {
|
public void parseWithMilsTest() {
|
||||||
final String dt = "2020-06-03 12:32:12,333";
|
final String dt = "2020-06-03 12:32:12,333";
|
||||||
final DateTime parse = DateUtil.parse(dt);
|
final DateTime parse = DateUtil.parse(dt);
|
||||||
assertEquals("2020-06-03 12:32:12", parse.toString());
|
assertEquals("2020-06-03 12:32:12", parse.toString());
|
||||||
|
@ -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"));
|
||||||
|
}
|
||||||
|
}
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user