add method for time

This commit is contained in:
Looly 2019-11-01 11:41:09 +08:00
parent b737c97947
commit 6e9879c821
7 changed files with 163 additions and 36 deletions

View File

@ -7,6 +7,9 @@
### 新特性
* 【core】 增加MapUtil.removeAnyissue#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的bugissue#I148GH@Gitee

View File

@ -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 新元素

View File

@ -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 时区IDnull表示当前系统默认的时区
* @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;
}
}

View File

@ -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;
}

View File

@ -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年第一季度

View File

@ -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();

View File

@ -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());
}
}