diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/ConverterRegistry.java b/hutool-core/src/main/java/cn/hutool/core/convert/ConverterRegistry.java index 4fd26839b..f49d01ad4 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/ConverterRegistry.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/ConverterRegistry.java @@ -13,11 +13,14 @@ import cn.hutool.core.convert.impl.ClassConverter; import cn.hutool.core.convert.impl.CollectionConverter; import cn.hutool.core.convert.impl.CurrencyConverter; import cn.hutool.core.convert.impl.DateConverter; +import cn.hutool.core.convert.impl.DurationConverter; import cn.hutool.core.convert.impl.EnumConverter; import cn.hutool.core.convert.impl.LocaleConverter; import cn.hutool.core.convert.impl.MapConverter; import cn.hutool.core.convert.impl.NumberConverter; +import cn.hutool.core.convert.impl.OptionalConverter; import cn.hutool.core.convert.impl.PathConverter; +import cn.hutool.core.convert.impl.PeriodConverter; import cn.hutool.core.convert.impl.PrimitiveConverter; import cn.hutool.core.convert.impl.ReferenceConverter; import cn.hutool.core.convert.impl.StackTraceElementConverter; @@ -43,18 +46,21 @@ import java.net.URI; import java.net.URL; import java.nio.charset.Charset; import java.nio.file.Path; +import java.time.Duration; import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.OffsetDateTime; import java.time.OffsetTime; +import java.time.Period; import java.time.ZonedDateTime; import java.util.Calendar; import java.util.Collection; import java.util.Currency; import java.util.Locale; import java.util.Map; +import java.util.Optional; import java.util.TimeZone; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; @@ -385,6 +391,8 @@ public class ConverterRegistry implements Serializable{ defaultConverterMap.put(ZonedDateTime.class, new TemporalAccessorConverter(ZonedDateTime.class)); defaultConverterMap.put(OffsetDateTime.class, new TemporalAccessorConverter(OffsetDateTime.class)); defaultConverterMap.put(OffsetTime.class, new TemporalAccessorConverter(OffsetTime.class)); + defaultConverterMap.put(Period.class, new PeriodConverter()); + defaultConverterMap.put(Duration.class, new DurationConverter()); // Reference defaultConverterMap.put(WeakReference.class, new ReferenceConverter(WeakReference.class));// since 3.0.8 @@ -400,6 +408,7 @@ public class ConverterRegistry implements Serializable{ defaultConverterMap.put(Currency.class, new CurrencyConverter());// since 3.0.8 defaultConverterMap.put(UUID.class, new UUIDConverter());// since 4.0.10 defaultConverterMap.put(StackTraceElement.class, new StackTraceElementConverter());// since 4.5.2 + defaultConverterMap.put(Optional.class, new OptionalConverter());// since 5.0.0 return this; } diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/impl/DurationConverter.java b/hutool-core/src/main/java/cn/hutool/core/convert/impl/DurationConverter.java new file mode 100644 index 000000000..972a89dca --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/convert/impl/DurationConverter.java @@ -0,0 +1,30 @@ +package cn.hutool.core.convert.impl; + +import cn.hutool.core.convert.AbstractConverter; + +import java.time.Duration; +import java.time.Period; +import java.time.temporal.TemporalAmount; + +/** + * + * {@link Duration}对象转换器 + * + * @author Looly + * @since 5.0.0 + */ +public class DurationConverter extends AbstractConverter { + private static final long serialVersionUID = 1L; + + @Override + protected Duration convertInternal(Object value) { + if(value instanceof TemporalAmount){ + return Duration.from((TemporalAmount) value); + } else if(value instanceof Long){ + return Duration.ofMillis((Long) value); + } else { + return Duration.parse(convertToStr(value)); + } + } + +} diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/impl/OptionalConverter.java b/hutool-core/src/main/java/cn/hutool/core/convert/impl/OptionalConverter.java new file mode 100644 index 000000000..ffeeacfcc --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/convert/impl/OptionalConverter.java @@ -0,0 +1,23 @@ +package cn.hutool.core.convert.impl; + +import cn.hutool.core.convert.AbstractConverter; + +import java.time.Period; +import java.util.Optional; + +/** + * + * {@link Optional}对象转换器 + * + * @author Looly + * @since 5.0.0 + */ +public class OptionalConverter extends AbstractConverter> { + private static final long serialVersionUID = 1L; + + @Override + protected Optional convertInternal(Object value) { + return Optional.ofNullable(value); + } + +} diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/impl/PeriodConverter.java b/hutool-core/src/main/java/cn/hutool/core/convert/impl/PeriodConverter.java new file mode 100644 index 000000000..3dd3224ba --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/convert/impl/PeriodConverter.java @@ -0,0 +1,30 @@ +package cn.hutool.core.convert.impl; + +import cn.hutool.core.convert.AbstractConverter; + +import java.time.Period; +import java.time.temporal.TemporalAmount; +import java.util.Optional; + +/** + * + * {@link Period}对象转换器 + * + * @author Looly + * @since 5.0.0 + */ +public class PeriodConverter extends AbstractConverter { + private static final long serialVersionUID = 1L; + + @Override + protected Period convertInternal(Object value) { + if(value instanceof TemporalAmount){ + return Period.from((TemporalAmount) value); + }else if(value instanceof Integer){ + return Period.ofDays((Integer) value); + } else { + return Period.parse(convertToStr(value)); + } + } + +} diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/impl/TemporalAccessorConverter.java b/hutool-core/src/main/java/cn/hutool/core/convert/impl/TemporalAccessorConverter.java index 4bbd13a56..90c3bc70c 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/impl/TemporalAccessorConverter.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/impl/TemporalAccessorConverter.java @@ -10,7 +10,6 @@ import java.time.LocalTime; import java.time.OffsetDateTime; import java.time.OffsetTime; import java.time.ZoneId; -import java.time.ZoneOffset; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import java.time.temporal.TemporalAccessor; diff --git a/hutool-core/src/main/java/cn/hutool/core/date/DateTime.java b/hutool-core/src/main/java/cn/hutool/core/date/DateTime.java index a5fb96be0..25181a571 100644 --- a/hutool-core/src/main/java/cn/hutool/core/date/DateTime.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/DateTime.java @@ -217,7 +217,6 @@ public class DateTime extends Date { * * @param dateStr Date字符串 * @param formatter 格式化器,{@link DateTimeFormatter} - * @return DateTime对象 * @since 5.0.0 */ public DateTime(CharSequence dateStr, DateTimeFormatter formatter) { diff --git a/hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java b/hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java index 9a356216a..00bc21db4 100644 --- a/hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/date/DateUtil.java @@ -545,6 +545,21 @@ public class DateUtil { return format.format(date); } + /** + * 根据特定格式格式化日期 + * + * @param date 被格式化的日期 + * @param format {@link SimpleDateFormat} + * @return 格式化后的字符串 + * @since 5.0.0 + */ + public static String format(Date date, DateTimeFormatter format) { + if (null == format || null == date) { + return null; + } + return format.format(date.toInstant()); + } + /** * 格式化日期时间
* 格式 yyyy-MM-dd HH:mm:ss diff --git a/hutool-core/src/test/java/cn/hutool/core/convert/TemporalAccessorConverterTest.java b/hutool-core/src/test/java/cn/hutool/core/convert/TemporalAccessorConverterTest.java index d8a3f987a..224715dba 100644 --- a/hutool-core/src/test/java/cn/hutool/core/convert/TemporalAccessorConverterTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/convert/TemporalAccessorConverterTest.java @@ -1,5 +1,6 @@ package cn.hutool.core.convert; +import cn.hutool.core.date.DateUtil; import org.junit.Assert; import org.junit.Test; @@ -15,8 +16,12 @@ public class TemporalAccessorConverterTest { @Test public void toInstantTest(){ - Instant instant = Convert.convert(Instant.class, "2019-02-18"); - Assert.assertNotNull(instant); + String dateStr = "2019-02-18"; + + // 通过转换获取的Instant为UTC时间 + Instant instant = Convert.convert(Instant.class, dateStr); + Instant instant1 = DateUtil.parse(dateStr).toInstant(); + Assert.assertEquals(instant1, instant); } @Test diff --git a/hutool-core/src/test/java/cn/hutool/core/io/FileUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/io/FileUtilTest.java index 1e88aa175..77ee214a7 100644 --- a/hutool-core/src/test/java/cn/hutool/core/io/FileUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/io/FileUtilTest.java @@ -75,7 +75,7 @@ public class FileUtilTest { } @Test - public void copyTest() throws Exception { + public void copyTest() { File srcFile = FileUtil.file("hutool.jpg"); File destFile = FileUtil.file("hutool.copy.jpg"); @@ -87,7 +87,7 @@ public class FileUtilTest { @Test @Ignore - public void copyFilesFromDir() throws Exception { + public void copyFilesFromDir() { File srcFile = FileUtil.file("D:\\驱动"); File destFile = FileUtil.file("d:\\驱动备份"); @@ -132,14 +132,18 @@ public class FileUtilTest { Assert.assertEquals("/bar", FileUtil.normalize("//server/../bar")); Assert.assertEquals("C:/bar", FileUtil.normalize("C:\\foo\\..\\bar")); Assert.assertEquals("C:/bar", FileUtil.normalize("C:\\..\\bar")); - Assert.assertEquals("~/bar/", FileUtil.normalize("~/foo/../bar/")); - Assert.assertEquals("bar", FileUtil.normalize("~/../bar")); Assert.assertEquals("bar", FileUtil.normalize("../../bar")); Assert.assertEquals("C:/bar", FileUtil.normalize("/C:/bar")); Assert.assertEquals("\\/192.168.1.1/Share/", FileUtil.normalize("\\\\192.168.1.1\\Share\\")); } + @Test + public void normalizeHomePathTest() { + String home = FileUtil.getUserHomePath().replace('\\', '/'); + Assert.assertEquals(home + "/bar/", FileUtil.normalize("~/foo/../bar/")); + } + @Test public void normalizeClassPathTest() { Assert.assertEquals("", FileUtil.normalize("classpath:"));