mirror of
https://gitee.com/dromara/hutool.git
synced 2025-04-05 17:37:59 +08:00
add method for time
This commit is contained in:
parent
b737c97947
commit
6e9879c821
@ -7,6 +7,9 @@
|
||||
|
||||
### 新特性
|
||||
* 【core】 增加MapUtil.removeAny(issue#612@Github)
|
||||
* 【core】 Convert.toList支持[1,2]字符串(issue#I149XN@Gitee)
|
||||
* 【core】 修正DateUtil.thisWeekOfMonth注释错误(issue#614@Github)
|
||||
* 【core】 DateUtil增加toLocalDate等方法,DateTime更好的支持时区
|
||||
|
||||
### Bug修复
|
||||
* 【db】 修复MetaUtil.getTableMeta()方法未释放ResultSet的bug(issue#I148GH@Gitee)
|
||||
|
@ -1744,6 +1744,7 @@ public class CollUtil {
|
||||
/**
|
||||
* 将指定对象全部加入到集合中<br>
|
||||
* 提供的对象如果为集合类型,会自动转换为目标元素类型<br>
|
||||
* 如果为String,支持类似于[1,2,3,4] 或者 1,2,3,4 这种格式
|
||||
*
|
||||
* @param <T> 元素类型
|
||||
* @param collection 被加入的集合
|
||||
@ -1772,7 +1773,8 @@ public class CollUtil {
|
||||
iter = new ArrayIter<>(value);
|
||||
} else if (value instanceof CharSequence) {
|
||||
// String按照逗号分隔的列表对待
|
||||
iter = StrUtil.splitTrim((CharSequence) value, CharUtil.COMMA).iterator();
|
||||
final String ArrayStr = StrUtil.unWrap((CharSequence) value, '[', ']');
|
||||
iter = StrUtil.splitTrim(ArrayStr, CharUtil.COMMA).iterator();
|
||||
} else {
|
||||
// 其它类型按照单一元素处理
|
||||
iter = CollUtil.newArrayList(value).iterator();
|
||||
@ -2415,7 +2417,7 @@ public class CollUtil {
|
||||
/**
|
||||
* 设置或增加元素。当index小于List的长度时,替换指定位置的值,否则在尾部追加
|
||||
*
|
||||
* @param <T> 元素类型
|
||||
* @param <T> 元素类型
|
||||
* @param list List列表
|
||||
* @param index 位置
|
||||
* @param element 新元素
|
||||
|
@ -1,7 +1,9 @@
|
||||
package cn.hutool.core.convert.impl;
|
||||
|
||||
import cn.hutool.core.convert.AbstractConverter;
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
@ -87,9 +89,11 @@ public class TemporalAccessorConverter extends AbstractConverter<TemporalAccesso
|
||||
} else if (value instanceof TemporalAccessor) {
|
||||
return parseFromTemporalAccessor((TemporalAccessor) value);
|
||||
} else if (value instanceof Date) {
|
||||
return parseFromInstant(((Date) value).toInstant());
|
||||
final DateTime dateTime = DateUtil.date((Date) value);
|
||||
return parseFromInstant(dateTime.toInstant(), dateTime.getZoneId());
|
||||
}else if (value instanceof Calendar) {
|
||||
return parseFromInstant(((Calendar) value).toInstant());
|
||||
final Calendar calendar = (Calendar) value;
|
||||
return parseFromInstant(calendar.toInstant(), calendar.getTimeZone().toZoneId());
|
||||
} else {
|
||||
return parseFromCharSequence(convertToStr(value));
|
||||
}
|
||||
@ -103,13 +107,17 @@ public class TemporalAccessorConverter extends AbstractConverter<TemporalAccesso
|
||||
*/
|
||||
private TemporalAccessor parseFromCharSequence(CharSequence value) {
|
||||
final Instant instant;
|
||||
ZoneId zoneId;
|
||||
if (null != this.format) {
|
||||
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(this.format);
|
||||
instant = formatter.parse(value, Instant::from);
|
||||
zoneId = formatter.getZone();
|
||||
} else {
|
||||
instant = DateUtil.parse(value).toInstant();
|
||||
final DateTime dateTime = DateUtil.parse(value);
|
||||
instant = dateTime.toInstant();
|
||||
zoneId = dateTime.getZoneId();
|
||||
}
|
||||
return parseFromInstant(instant);
|
||||
return parseFromInstant(instant, zoneId);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -119,7 +127,7 @@ public class TemporalAccessorConverter extends AbstractConverter<TemporalAccesso
|
||||
* @return java.time中的对象
|
||||
*/
|
||||
private TemporalAccessor parseFromLong(Long time) {
|
||||
return parseFromInstant(Instant.ofEpochMilli(time));
|
||||
return parseFromInstant(Instant.ofEpochMilli(time), null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -137,7 +145,7 @@ public class TemporalAccessorConverter extends AbstractConverter<TemporalAccesso
|
||||
}
|
||||
|
||||
if(null == result){
|
||||
result = parseFromInstant(DateUtil.toInstant(temporalAccessor));
|
||||
result = parseFromInstant(DateUtil.toInstant(temporalAccessor), null);
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -205,24 +213,30 @@ public class TemporalAccessorConverter extends AbstractConverter<TemporalAccesso
|
||||
* 将TemporalAccessor型时间戳转换为java.time中的对象
|
||||
*
|
||||
* @param instant {@link Instant}对象
|
||||
* @param zoneId 时区ID,null表示当前系统默认的时区
|
||||
* @return java.time中的对象
|
||||
*/
|
||||
private TemporalAccessor parseFromInstant(Instant instant) {
|
||||
private TemporalAccessor parseFromInstant(Instant instant, ZoneId zoneId) {
|
||||
if(Instant.class.equals(this.targetType)){
|
||||
return instant;
|
||||
}else if (LocalDateTime.class.equals(this.targetType)) {
|
||||
return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
|
||||
} else if (LocalDate.class.equals(this.targetType)) {
|
||||
return instant.atZone(ZoneId.systemDefault()).toLocalDate();
|
||||
} else if (LocalTime.class.equals(this.targetType)) {
|
||||
return instant.atZone(ZoneId.systemDefault()).toLocalTime();
|
||||
} else if (ZonedDateTime.class.equals(this.targetType)) {
|
||||
return instant.atZone(ZoneId.systemDefault());
|
||||
} else if (OffsetDateTime.class.equals(this.targetType)) {
|
||||
return OffsetDateTime.ofInstant(instant, ZoneId.systemDefault());
|
||||
} else if (OffsetTime.class.equals(this.targetType)) {
|
||||
return OffsetTime.ofInstant(instant, ZoneId.systemDefault());
|
||||
}
|
||||
return null;
|
||||
|
||||
zoneId = ObjectUtil.defaultIfNull(zoneId, ZoneId.systemDefault());
|
||||
|
||||
TemporalAccessor result = null;
|
||||
if (LocalDateTime.class.equals(this.targetType)) {
|
||||
result = LocalDateTime.ofInstant(instant, zoneId);
|
||||
} else if (LocalDate.class.equals(this.targetType)) {
|
||||
result = instant.atZone(zoneId).toLocalDate();
|
||||
} else if (LocalTime.class.equals(this.targetType)) {
|
||||
result = instant.atZone(zoneId).toLocalTime();
|
||||
} else if (ZonedDateTime.class.equals(this.targetType)) {
|
||||
result = instant.atZone(zoneId);
|
||||
} else if (OffsetDateTime.class.equals(this.targetType)) {
|
||||
result = OffsetDateTime.ofInstant(instant, zoneId);
|
||||
} else if (OffsetTime.class.equals(this.targetType)) {
|
||||
result = OffsetTime.ofInstant(instant, zoneId);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,8 @@ import java.sql.Timestamp;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.TemporalAccessor;
|
||||
import java.util.Calendar;
|
||||
@ -156,6 +158,17 @@ public class DateTime extends Date {
|
||||
this(instant.toEpochMilli());
|
||||
}
|
||||
|
||||
/**
|
||||
* 给定日期Instant的构造
|
||||
*
|
||||
* @param instant {@link Instant} 对象
|
||||
* @param zoneId 时区ID
|
||||
* @since 5.0.5
|
||||
*/
|
||||
public DateTime(Instant instant, ZoneId zoneId) {
|
||||
this(instant.toEpochMilli(), TimeZone.getTimeZone(ObjectUtil.defaultIfNull(zoneId, ZoneId.systemDefault())));
|
||||
}
|
||||
|
||||
/**
|
||||
* 给定日期TemporalAccessor的构造
|
||||
*
|
||||
@ -166,6 +179,16 @@ public class DateTime extends Date {
|
||||
this(DateUtil.toInstant(temporalAccessor));
|
||||
}
|
||||
|
||||
/**
|
||||
* 给定日期ZonedDateTime的构造
|
||||
*
|
||||
* @param zonedDateTime {@link ZonedDateTime} 对象
|
||||
* @since 5.0.5
|
||||
*/
|
||||
public DateTime(ZonedDateTime zonedDateTime) {
|
||||
this(zonedDateTime.toInstant(), zonedDateTime.getZone());
|
||||
}
|
||||
|
||||
/**
|
||||
* 给定日期毫秒数的构造
|
||||
*
|
||||
@ -185,9 +208,7 @@ public class DateTime extends Date {
|
||||
*/
|
||||
public DateTime(long timeMillis, TimeZone timeZone) {
|
||||
super(timeMillis);
|
||||
if (null != timeZone) {
|
||||
this.timeZone = timeZone;
|
||||
}
|
||||
this.timeZone = ObjectUtil.defaultIfNull(timeZone, TimeZone.getDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -215,12 +236,12 @@ public class DateTime extends Date {
|
||||
/**
|
||||
* 构建DateTime对象
|
||||
*
|
||||
* @param dateStr Date字符串
|
||||
* @param dateStr Date字符串
|
||||
* @param formatter 格式化器,{@link DateTimeFormatter}
|
||||
* @since 5.0.0
|
||||
*/
|
||||
public DateTime(CharSequence dateStr, DateTimeFormatter formatter) {
|
||||
this(Instant.from(formatter.parse(dateStr)));
|
||||
this(Instant.from(formatter.parse(dateStr)), formatter.getZone());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -770,6 +791,26 @@ public class DateTime extends Date {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取时区
|
||||
*
|
||||
* @return 时区
|
||||
* @since 5.0.5
|
||||
*/
|
||||
public TimeZone getTimeZone(){
|
||||
return this.timeZone;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取时区ID
|
||||
*
|
||||
* @return 时区ID
|
||||
* @since 5.0.5
|
||||
*/
|
||||
public ZoneId getZoneId(){
|
||||
return this.timeZone.toZoneId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置时区
|
||||
*
|
||||
@ -778,7 +819,7 @@ public class DateTime extends Date {
|
||||
* @since 4.1.2
|
||||
*/
|
||||
public DateTime setTimeZone(TimeZone timeZone) {
|
||||
this.timeZone = timeZone;
|
||||
this.timeZone = ObjectUtil.defaultIfNull(timeZone, TimeZone.getDefault());
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -407,7 +407,7 @@ public class DateUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 当前日期所在年份的第几周
|
||||
* @return 当前日期所在月份的第几周
|
||||
*/
|
||||
public static int thisWeekOfMonth() {
|
||||
return weekOfMonth(date());
|
||||
@ -1966,6 +1966,17 @@ public class DateUtil {
|
||||
return null == date ? null : date.toInstant();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calendar{@link Instant}对象
|
||||
*
|
||||
* @param calendar Date对象
|
||||
* @return {@link Instant}对象
|
||||
* @since 5.0.5
|
||||
*/
|
||||
public static Instant toInstant(Calendar calendar) {
|
||||
return null == calendar ? null : calendar.toInstant();
|
||||
}
|
||||
|
||||
/**
|
||||
* Date对象转换为{@link Instant}对象
|
||||
*
|
||||
@ -2001,8 +2012,42 @@ public class DateUtil {
|
||||
|
||||
return result;
|
||||
}
|
||||
// ------------------------------------------------------------------------ Private method start
|
||||
|
||||
/**
|
||||
* {@link Instant} 转换为 {@link LocalDateTime},使用系统默认时区
|
||||
*
|
||||
* @param instant {@link Instant}
|
||||
* @return {@link LocalDateTime}
|
||||
* @since 5.0.5
|
||||
*/
|
||||
public static LocalDateTime toLocalDateTime(Instant instant){
|
||||
return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Calendar} 转换为 {@link LocalDateTime},使用系统默认时区
|
||||
*
|
||||
* @param calendar {@link Calendar}
|
||||
* @return {@link LocalDateTime}
|
||||
* @since 5.0.5
|
||||
*/
|
||||
public static LocalDateTime toLocalDateTime(Calendar calendar){
|
||||
return LocalDateTime.ofInstant(calendar.toInstant(), calendar.getTimeZone().toZoneId());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Date} 转换为 {@link LocalDateTime},使用系统默认时区
|
||||
*
|
||||
* @param date {@link Calendar}
|
||||
* @return {@link LocalDateTime}
|
||||
* @since 5.0.5
|
||||
*/
|
||||
public static LocalDateTime toLocalDateTime(Date date){
|
||||
final DateTime dateTime = date(date);
|
||||
return LocalDateTime.ofInstant(dateTime.toInstant(), dateTime.getZoneId());
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------ Private method start
|
||||
/**
|
||||
* 获得指定日期年份和季节<br>
|
||||
* 格式:[20131]表示2013年第一季度
|
||||
|
@ -102,12 +102,7 @@ public class ThreadUtil {
|
||||
* @return 执行的方法体
|
||||
*/
|
||||
public static Runnable excAsync(final Runnable runnable, boolean isDaemon) {
|
||||
Thread thread = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
runnable.run();
|
||||
}
|
||||
};
|
||||
Thread thread = new Thread(runnable);
|
||||
thread.setDaemon(isDaemon);
|
||||
thread.start();
|
||||
|
||||
|
@ -4,6 +4,8 @@ import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 类型转换工具单元测试
|
||||
@ -179,4 +181,29 @@ public class ConvertTest {
|
||||
|
||||
Assert.assertEquals(short2, short1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toListTest(){
|
||||
List<String> list = Arrays.asList("1","2");
|
||||
String str = Convert.toStr(list);
|
||||
List<String> list2 = Convert.toList(String.class, str);
|
||||
Assert.assertEquals("1", list2.get(0));
|
||||
Assert.assertEquals("2", list2.get(1));
|
||||
|
||||
List<Integer> list3 = Convert.toList(Integer.class, str);
|
||||
Assert.assertEquals(1, list3.get(0).intValue());
|
||||
Assert.assertEquals(2, list3.get(1).intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toListTest2(){
|
||||
String str = "1,2";
|
||||
List<String> list2 = Convert.toList(String.class, str);
|
||||
Assert.assertEquals("1", list2.get(0));
|
||||
Assert.assertEquals("2", list2.get(1));
|
||||
|
||||
List<Integer> list3 = Convert.toList(Integer.class, str);
|
||||
Assert.assertEquals(1, list3.get(0).intValue());
|
||||
Assert.assertEquals(2, list3.get(1).intValue());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user