mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
fix code
This commit is contained in:
parent
e56e10b75c
commit
85fac17eac
@ -53,6 +53,8 @@ public final class DateBuilder {
|
||||
private int ns;
|
||||
// Unix时间戳(秒)
|
||||
private long unixsecond;
|
||||
// 时间戳(毫秒)
|
||||
private long millisecond;
|
||||
// 时区偏移量是否已设置
|
||||
private boolean zoneOffsetSetted;
|
||||
// 时区偏移量(分钟)
|
||||
@ -247,6 +249,26 @@ public final class DateBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取时间戳(毫秒)。
|
||||
*
|
||||
* @return 当前对象的时间戳(以毫秒为单位)。
|
||||
*/
|
||||
public long getMillisecond() {
|
||||
return millisecond;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置时间戳(毫秒)。
|
||||
*
|
||||
* @param millisecond 要设置的时间戳(以毫秒为单位)。
|
||||
* @return this
|
||||
*/
|
||||
public DateBuilder setMillisecond(final long millisecond) {
|
||||
this.millisecond = millisecond;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查时区偏移量是否已设置。
|
||||
*
|
||||
@ -363,6 +385,7 @@ public final class DateBuilder {
|
||||
this.second = 0;
|
||||
this.ns = 0;
|
||||
this.unixsecond = 0;
|
||||
this.millisecond = 0;
|
||||
this.am = false;
|
||||
this.pm = false;
|
||||
this.zoneOffsetSetted = false;
|
||||
@ -403,12 +426,6 @@ public final class DateBuilder {
|
||||
this.prepare();
|
||||
final Calendar calendar = Calendar.getInstance(); // 获取一个Calendar实例
|
||||
|
||||
// 如果有unix时间戳,则据此设置时间
|
||||
if (unixsecond != 0) {
|
||||
calendar.setTimeInMillis(unixsecond * 1000 + ns / 1_000_000); // 设置时间戳对应的毫秒数
|
||||
return calendar;
|
||||
}
|
||||
|
||||
// 设置时区
|
||||
if (zone != null) {
|
||||
calendar.setTimeZone(zone); // 使用指定的时区
|
||||
@ -421,6 +438,18 @@ public final class DateBuilder {
|
||||
calendar.setTimeZone(TimeZone.getTimeZone(ids[0])); // 设置第一个找到的时区
|
||||
}
|
||||
|
||||
// 如果毫秒数不为0,则直接使用毫秒数设置时间
|
||||
if(millisecond != 0){
|
||||
calendar.setTimeInMillis(millisecond);
|
||||
return calendar;
|
||||
}
|
||||
|
||||
// 如果有unix时间戳,则据此设置时间
|
||||
if (unixsecond != 0) {
|
||||
calendar.setTimeInMillis(unixsecond * 1000 + ns / 1_000_000); // 设置时间戳对应的毫秒数
|
||||
return calendar;
|
||||
}
|
||||
|
||||
// 设置日期和时间字段
|
||||
calendar.set(Calendar.YEAR, year);
|
||||
calendar.set(Calendar.MONTH, month - 1); // Calendar的月份从0开始
|
||||
@ -443,6 +472,11 @@ public final class DateBuilder {
|
||||
LocalDateTime toLocalDateTime() {
|
||||
this.prepare();
|
||||
|
||||
if(millisecond > 0){
|
||||
final Instant instant = Instant.ofEpochMilli(millisecond);
|
||||
return LocalDateTime.ofEpochSecond(instant.getEpochSecond(), instant.getNano(), DEFAULT_OFFSET);
|
||||
}
|
||||
|
||||
// 如果unixsecond大于0,使用unix时间戳创建LocalDateTime
|
||||
if (unixsecond > 0) {
|
||||
return LocalDateTime.ofEpochSecond(unixsecond, ns, DEFAULT_OFFSET);
|
||||
@ -480,6 +514,10 @@ public final class DateBuilder {
|
||||
OffsetDateTime toOffsetDateTime() {
|
||||
this.prepare(); // 准备工作,可能涉及一些初始化或数据处理
|
||||
|
||||
if(millisecond > 0){
|
||||
return OffsetDateTime.ofInstant(Instant.ofEpochMilli(millisecond), ZoneUtil.ZONE_ID_UTC);
|
||||
}
|
||||
|
||||
if (unixsecond > 0) {
|
||||
// 如果设置了 unix 时间戳,则使用它和纳秒创建 UTC 时间
|
||||
return OffsetDateTime.ofInstant(Instant.ofEpochSecond(unixsecond, ns), ZoneUtil.ZONE_ID_UTC);
|
||||
|
@ -24,33 +24,41 @@ import java.util.regex.Pattern;
|
||||
*/
|
||||
public class GlobalRegexDateParser {
|
||||
|
||||
private static final String yearRegex = "(?<year>\\d{2,4})";
|
||||
private static final String monthRegex = "(?<month>\\w{3,9})";
|
||||
private static final String dayRegex = "(?<day>\\d{1,2})(?:th)?";
|
||||
// 周的正则,匹配:Mon, Tue, Wed, Thu, Fri, Sat, Sun,或 Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
|
||||
// 日期中一般出现在头部,可选
|
||||
private static final String weekRegex = "(?<week>[mwfts][oeruha][ndieut](\\w{3,6})?\\W+)?";
|
||||
// hh:mm:ss.SSSSZ hh:mm:ss.SSSS hh:mm:ss hh:mm
|
||||
private static final String timeRegex = "(" +
|
||||
"\\s(?<hour>\\d{1,2})" +
|
||||
"\\W+(?<hour>\\d{1,2})" +
|
||||
":(?<minute>\\d{1,2})" +
|
||||
"(:(?<second>\\d{1,2}))?" +
|
||||
"(?:[.,](?<ns>\\d{1,9}))?(?<zero>z)?" +
|
||||
"(\\s?(?<m>am|pm))?" +
|
||||
"(\\s?(?<m>[ap]m))?" +
|
||||
")?";
|
||||
// +08:00 +0800 +08
|
||||
// 时区,类似: +08:00 +0800 +08,可选
|
||||
private static final String zoneOffsetRegex = "(\\s?(?<zoneOffset>[-+]\\d{1,2}:?(?:\\d{2})?))?";
|
||||
// CST UTC (CST)
|
||||
// 时区名称,类似: CST UTC (CST),可选
|
||||
private static final String zoneNameRegex = "(\\s[(]?(?<zoneName>[a-z ]+)[)]?)?";
|
||||
|
||||
private static final RegexDateParser PARSER;
|
||||
|
||||
static {
|
||||
final String dateRegexMonthFirst = "(?<month>\\w+{3,9})\\W+(?<day>\\d{1,2})(?:th)?\\W+(?<year>\\d{2,4})";
|
||||
// 月开头,类似:May 8
|
||||
final String dateRegexMonthFirst = monthRegex + "\\W+" + dayRegex;
|
||||
|
||||
PARSER = RegexDateParser.of(
|
||||
// 年开头
|
||||
|
||||
//月开头,类似:May 8, 2009 5:57:51
|
||||
dateRegexMonthFirst + timeRegex + zoneOffsetRegex
|
||||
|
||||
// 周开头
|
||||
//月在前,类似:May 8, 2009,时间部分可选,类似:5:57:51,5:57:51 +08:00
|
||||
weekRegex + dateRegexMonthFirst + "\\W+" + yearRegex + timeRegex + zoneOffsetRegex,
|
||||
// 年在最后,类似:Mon Jan 2 15:04:05 MST 2006
|
||||
weekRegex + dateRegexMonthFirst + timeRegex + zoneNameRegex + zoneOffsetRegex + "\\W+" + yearRegex
|
||||
|
||||
// 日开头
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ import org.dromara.hutool.core.collection.ListUtil;
|
||||
import org.dromara.hutool.core.date.*;
|
||||
import org.dromara.hutool.core.lang.Opt;
|
||||
import org.dromara.hutool.core.regex.ReUtil;
|
||||
import org.dromara.hutool.core.text.CharUtil;
|
||||
import org.dromara.hutool.core.text.StrUtil;
|
||||
|
||||
import java.io.Serializable;
|
||||
@ -95,11 +96,13 @@ public class RegexDateParser implements DateParser, Serializable {
|
||||
|
||||
@Override
|
||||
public Date parse(final CharSequence source) throws DateException {
|
||||
final DateBuilder dateBuilder = DateBuilder.of();
|
||||
Matcher matcher;
|
||||
for (final Pattern pattern : this.patterns) {
|
||||
matcher = pattern.matcher(source);
|
||||
if (matcher.matches()) {
|
||||
return parse(matcher);
|
||||
parse(matcher, dateBuilder);
|
||||
return dateBuilder.toDate();
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,17 +113,16 @@ public class RegexDateParser implements DateParser, Serializable {
|
||||
* 解析日期
|
||||
*
|
||||
* @param matcher 正则匹配器
|
||||
* @return 日期
|
||||
* @throws DateException 日期解析异常
|
||||
*/
|
||||
private static Date parse(final Matcher matcher) throws DateException {
|
||||
private static void parse(final Matcher matcher, final DateBuilder dateBuilder) throws DateException {
|
||||
// 毫秒时间戳
|
||||
final String millisecond = ReUtil.group(matcher, "millisecond");
|
||||
if (StrUtil.isNotEmpty(millisecond)) {
|
||||
return DateUtil.date(parseLong(millisecond));
|
||||
dateBuilder.setMillisecond(parseLong(millisecond));
|
||||
return;
|
||||
}
|
||||
|
||||
final DateBuilder dateBuilder = DateBuilder.of();
|
||||
// year
|
||||
Opt.ofNullable(ReUtil.group(matcher, "year")).ifPresent((year) -> dateBuilder.setYear(parseYear(year)));
|
||||
// month
|
||||
@ -139,7 +141,7 @@ public class RegexDateParser implements DateParser, Serializable {
|
||||
Opt.ofNullable(ReUtil.group(matcher, "ns")).ifPresent((ns) -> dateBuilder.setNs(parseNano(ns)));
|
||||
// am or pm
|
||||
Opt.ofNullable(ReUtil.group(matcher, "m")).ifPresent((m) -> {
|
||||
if ('p' == m.charAt(0)) {
|
||||
if (CharUtil.equals('p', m.charAt(0), true)) {
|
||||
dateBuilder.setPm(true);
|
||||
} else {
|
||||
dateBuilder.setAm(true);
|
||||
@ -158,12 +160,15 @@ public class RegexDateParser implements DateParser, Serializable {
|
||||
dateBuilder.setZoneOffset(parseZoneOffset(zoneOffset));
|
||||
});
|
||||
|
||||
// zone name
|
||||
Opt.ofNullable(ReUtil.group(matcher, "zoneName")).ifPresent((zoneOffset) -> {
|
||||
// 暂时不支持解析
|
||||
});
|
||||
|
||||
// unix时间戳
|
||||
Opt.ofNullable(ReUtil.group(matcher, "unixsecond")).ifPresent((unixsecond) -> {
|
||||
dateBuilder.setUnixsecond(parseLong(unixsecond));
|
||||
});
|
||||
|
||||
return dateBuilder.toDate();
|
||||
}
|
||||
|
||||
private static int parseYear(final String year) {
|
||||
|
@ -0,0 +1,45 @@
|
||||
package org.dromara.hutool.core.date.format.parser;
|
||||
|
||||
import org.dromara.hutool.core.date.DateUtil;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class GlobalRegexDateParserTest {
|
||||
|
||||
@Test
|
||||
void parseMonthFirstTest() {
|
||||
assertParse("2009-05-08 05:57:51", "May 8, 2009 5:57:51");
|
||||
assertParse("2009-05-08 17:57:51", "May 8, 2009 5:57:51 PM");
|
||||
assertParse("2009-05-08 17:57:51", "May 8, 2009 5:57:51 pm");
|
||||
assertParse("2009-05-08 17:57:51", "May 8, 2009 5:57:51pm");
|
||||
assertParse("2009-05-08 05:57:51", "May 8, 2009 5:57:51 +08:00");
|
||||
assertParse("2009-05-08 05:57:51", "May 8, 2009 5:57:51 +0800");
|
||||
assertParse("2009-05-08 05:57:51", "May 8, 2009 5:57:51 +08");
|
||||
assertParse("2009-05-08 00:00:00", "May 8, 2009");
|
||||
assertParse("2009-05-08 00:00:00", "May 8th, 2009");
|
||||
assertParse("2009-05-08 00:00:00", "May 8th, 09");
|
||||
assertParse("2009-05-08 00:00:00", "may. 8th, 09");
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseWeekFirstTest() {
|
||||
assertParse("2006-01-02 15:04:05", "Mon Jan 2, 2006 15:04:05");
|
||||
assertParse("2006-01-02 15:04:05", "Mon Jan 2 2006 15:04:05");
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseWeekFirstYearLastTest() {
|
||||
assertParse("2006-01-02 15:04:05", "Mon Jan 2 15:04:05 2006");
|
||||
assertParse("2006-01-02 15:04:05", "Mon Jan 2 15:04:05 MST 2006");
|
||||
assertParse("2006-01-03 06:04:05", "Mon Jan 02 15:04:05 -0700 2006");
|
||||
//assertParse("2006-01-03 06:04:05", "Monday, 02-Jan-06 15:04:05 MST");
|
||||
}
|
||||
|
||||
private static void assertParse(final String dateStr, final String dateStrToParse) {
|
||||
final Date date = GlobalRegexDateParser.parse(dateStrToParse);
|
||||
assertEquals(dateStr, DateUtil.date(date).toString());
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package org.dromara.hutool.core.date.format.parser;
|
||||
|
||||
import org.dromara.hutool.core.date.DateUtil;
|
||||
import org.dromara.hutool.core.date.Week;
|
||||
import org.dromara.hutool.core.regex.ReUtil;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@ -59,6 +60,15 @@ public class RegexDateParserTest {
|
||||
assertMatch(zoneNameRegex, " (GMT Daylight Time)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void weekMatchTest() {
|
||||
final String weekRegex = "(?<week>[mwfts][oeruha][ndieut](\\w{3,6})?)";
|
||||
for (final Week week : Week.values()) {
|
||||
assertMatch(weekRegex, week.name());
|
||||
assertMatch(weekRegex, week.name().substring(0, 3));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void parsePureTest() {
|
||||
// yyyyMMdd
|
||||
|
Loading…
x
Reference in New Issue
Block a user