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】 增加MapUtil.removeAnyissue#612@Github
* 【core】 Convert.toList支持[1,2]字符串issue#I149XN@Gitee
* 【core】 修正DateUtil.thisWeekOfMonth注释错误issue#614@Github
* 【core】 DateUtil增加toLocalDate等方法DateTime更好的支持时区
### Bug修复 ### Bug修复
* 【db】 修复MetaUtil.getTableMeta()方法未释放ResultSet的bugissue#I148GH@Gitee * 【db】 修复MetaUtil.getTableMeta()方法未释放ResultSet的bugissue#I148GH@Gitee

View File

@ -1744,6 +1744,7 @@ public class CollUtil {
/** /**
* 将指定对象全部加入到集合中<br> * 将指定对象全部加入到集合中<br>
* 提供的对象如果为集合类型会自动转换为目标元素类型<br> * 提供的对象如果为集合类型会自动转换为目标元素类型<br>
* 如果为String支持类似于[1,2,3,4] 或者 1,2,3,4 这种格式
* *
* @param <T> 元素类型 * @param <T> 元素类型
* @param collection 被加入的集合 * @param collection 被加入的集合
@ -1772,7 +1773,8 @@ public class CollUtil {
iter = new ArrayIter<>(value); iter = new ArrayIter<>(value);
} else if (value instanceof CharSequence) { } else if (value instanceof CharSequence) {
// String按照逗号分隔的列表对待 // String按照逗号分隔的列表对待
iter = StrUtil.splitTrim((CharSequence) value, CharUtil.COMMA).iterator(); final String ArrayStr = StrUtil.unWrap((CharSequence) value, '[', ']');
iter = StrUtil.splitTrim(ArrayStr, CharUtil.COMMA).iterator();
} else { } else {
// 其它类型按照单一元素处理 // 其它类型按照单一元素处理
iter = CollUtil.newArrayList(value).iterator(); iter = CollUtil.newArrayList(value).iterator();
@ -2415,7 +2417,7 @@ public class CollUtil {
/** /**
* 设置或增加元素当index小于List的长度时替换指定位置的值否则在尾部追加 * 设置或增加元素当index小于List的长度时替换指定位置的值否则在尾部追加
* *
* @param <T> 元素类型 * @param <T> 元素类型
* @param list List列表 * @param list List列表
* @param index 位置 * @param index 位置
* @param element 新元素 * @param element 新元素

View File

@ -1,7 +1,9 @@
package cn.hutool.core.convert.impl; package cn.hutool.core.convert.impl;
import cn.hutool.core.convert.AbstractConverter; import cn.hutool.core.convert.AbstractConverter;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import java.time.Instant; import java.time.Instant;
import java.time.LocalDate; import java.time.LocalDate;
@ -87,9 +89,11 @@ public class TemporalAccessorConverter extends AbstractConverter<TemporalAccesso
} else if (value instanceof TemporalAccessor) { } else if (value instanceof TemporalAccessor) {
return parseFromTemporalAccessor((TemporalAccessor) value); return parseFromTemporalAccessor((TemporalAccessor) value);
} else if (value instanceof Date) { } 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) { }else if (value instanceof Calendar) {
return parseFromInstant(((Calendar) value).toInstant()); final Calendar calendar = (Calendar) value;
return parseFromInstant(calendar.toInstant(), calendar.getTimeZone().toZoneId());
} else { } else {
return parseFromCharSequence(convertToStr(value)); return parseFromCharSequence(convertToStr(value));
} }
@ -103,13 +107,17 @@ public class TemporalAccessorConverter extends AbstractConverter<TemporalAccesso
*/ */
private TemporalAccessor parseFromCharSequence(CharSequence value) { private TemporalAccessor parseFromCharSequence(CharSequence value) {
final Instant instant; final Instant instant;
ZoneId zoneId;
if (null != this.format) { if (null != this.format) {
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(this.format); final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(this.format);
instant = formatter.parse(value, Instant::from); instant = formatter.parse(value, Instant::from);
zoneId = formatter.getZone();
} else { } 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中的对象 * @return java.time中的对象
*/ */
private TemporalAccessor parseFromLong(Long 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){ if(null == result){
result = parseFromInstant(DateUtil.toInstant(temporalAccessor)); result = parseFromInstant(DateUtil.toInstant(temporalAccessor), null);
} }
return result; return result;
@ -205,24 +213,30 @@ public class TemporalAccessorConverter extends AbstractConverter<TemporalAccesso
* 将TemporalAccessor型时间戳转换为java.time中的对象 * 将TemporalAccessor型时间戳转换为java.time中的对象
* *
* @param instant {@link Instant}对象 * @param instant {@link Instant}对象
* @param zoneId 时区IDnull表示当前系统默认的时区
* @return java.time中的对象 * @return java.time中的对象
*/ */
private TemporalAccessor parseFromInstant(Instant instant) { private TemporalAccessor parseFromInstant(Instant instant, ZoneId zoneId) {
if(Instant.class.equals(this.targetType)){ if(Instant.class.equals(this.targetType)){
return instant; 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.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.time.Instant; import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalAccessor;
import java.util.Calendar; import java.util.Calendar;
@ -156,6 +158,17 @@ public class DateTime extends Date {
this(instant.toEpochMilli()); 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的构造 * 给定日期TemporalAccessor的构造
* *
@ -166,6 +179,16 @@ public class DateTime extends Date {
this(DateUtil.toInstant(temporalAccessor)); 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) { public DateTime(long timeMillis, TimeZone timeZone) {
super(timeMillis); super(timeMillis);
if (null != timeZone) { this.timeZone = ObjectUtil.defaultIfNull(timeZone, TimeZone.getDefault());
this.timeZone = timeZone;
}
} }
/** /**
@ -215,12 +236,12 @@ public class DateTime extends Date {
/** /**
* 构建DateTime对象 * 构建DateTime对象
* *
* @param dateStr Date字符串 * @param dateStr Date字符串
* @param formatter 格式化器,{@link DateTimeFormatter} * @param formatter 格式化器,{@link DateTimeFormatter}
* @since 5.0.0 * @since 5.0.0
*/ */
public DateTime(CharSequence dateStr, DateTimeFormatter formatter) { 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 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 * @since 4.1.2
*/ */
public DateTime setTimeZone(TimeZone timeZone) { public DateTime setTimeZone(TimeZone timeZone) {
this.timeZone = timeZone; this.timeZone = ObjectUtil.defaultIfNull(timeZone, TimeZone.getDefault());
return this; return this;
} }

View File

@ -407,7 +407,7 @@ public class DateUtil {
} }
/** /**
* @return 当前日期所在份的第几周 * @return 当前日期所在份的第几周
*/ */
public static int thisWeekOfMonth() { public static int thisWeekOfMonth() {
return weekOfMonth(date()); return weekOfMonth(date());
@ -1966,6 +1966,17 @@ public class DateUtil {
return null == date ? null : date.toInstant(); 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}对象 * Date对象转换为{@link Instant}对象
* *
@ -2001,8 +2012,42 @@ public class DateUtil {
return result; 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> * 获得指定日期年份和季节<br>
* 格式[20131]表示2013年第一季度 * 格式[20131]表示2013年第一季度

View File

@ -102,12 +102,7 @@ public class ThreadUtil {
* @return 执行的方法体 * @return 执行的方法体
*/ */
public static Runnable excAsync(final Runnable runnable, boolean isDaemon) { public static Runnable excAsync(final Runnable runnable, boolean isDaemon) {
Thread thread = new Thread() { Thread thread = new Thread(runnable);
@Override
public void run() {
runnable.run();
}
};
thread.setDaemon(isDaemon); thread.setDaemon(isDaemon);
thread.start(); thread.start();

View File

@ -4,6 +4,8 @@ import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/** /**
* 类型转换工具单元测试 * 类型转换工具单元测试
@ -179,4 +181,29 @@ public class ConvertTest {
Assert.assertEquals(short2, short1); 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());
}
} }