紧接着上篇文章Random和SimpleDateFormat的坑和最佳实践
为什么是线程安全的?
还是看源代码和注释说
* This class is immutable and thread-safe.
*
* @since 1.8
*/
public final class DateTimeFormatter {}
很明显,通过final关键字,做成了不可变类,类似String,不仅线程安全而且高效。
进行格式化的方法ofPattern()一直适用吗?
通常使用来说,我们可以通过
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
or
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("E, yyyy-MMMM-dd HH:mm", Locale.US);
or
DateTimeFormatter formatterTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.of("+8"));
以上,都是OK的,而且也是最长被用到的,但是不会一直正确,如下:
DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmssS");
LocalDateTime dt1 = LocalDateTime.parse("20190510134643946", DATE_TIME_FORMATTER);
System.out.println(dt1);
异常如下:
Exception in thread "main" java.time.format.DateTimeParseException: Text '20190510134643946' could not be parsed at index 0
at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
at java.time.LocalDateTime.parse(LocalDateTime.java:492)
at com.feeler.interlive.main.FirstCommon.test28(FirstCommon.java:71)
at com.feeler.interlive.main.FirstCommon.main(FirstCommon.java:65)
那么该怎么做呢?
DateTimeFormatter DATE_TIME_FORMATTER = new DateTimeFormatterBuilder()
// 解析date+time
.appendPattern("yyyyMMddHHmmss")
// 解析毫秒数
.appendValue(ChronoField.MILLI_OF_SECOND, 3)
.toFormatter();
DateTimeFormatter中的常用转换
1. LocalDateTime 转化为Date
//将java.util.Date 转换为java8 的java.time.LocalDateTime,默认时区为东8区
public static LocalDateTime dateConvertToLocalDateTime(Date date) {
return date.toInstant().atOffset(ZoneOffset.of("+8")).toLocalDateTime();
}
//将java8 的 java.time.LocalDateTime 转换为 java.util.Date,默认时区为东8区
public static Date localDateTimeConvertToDate(LocalDateTime localDateTime) {
return Date.from(localDateTime.toInstant(ZoneOffset.of("+8")));
}
2. LocalDateTime转秒级时间戳、转毫秒时间戳(此处容易入坑)
String updateTime = "2019-07-28 14:11:15";
DateTimeFormatter formatterTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.of("+8"));
LocalDateTime lastLDT = LocalDateTime.parse(updateTime, formatterTime);
//获取秒级
long last = lastLDT.toEpochSecond(ZoneOffset.of("+8"));
//获取毫秒级
long last = lastLDT.toInstant(ZoneOffset.of("+8")).toEpochMilli();
3. LocalDateTime转换String
//时间转字符串格式化
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
String dateTime = LocalDateTime.now(ZoneOffset.of("+8")).format(formatter);
//字符串转时间
String dateTimeStr = "2018-07-28 14:11:15";
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime dateTime = LocalDateTime.parse(dateTimeStr, df);
4. 获取当前的秒级和毫秒级时间戳
//获取秒数
Long second = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
//获取毫秒数
Long milliSecond = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
总结,可以使用Instant代替 Date,LocalDateTime代替 Calendar,DateTimeFormatter 代替 SimpleDateFormat。
Reference:
https://blog.csdn.net/u014044812/article/details/79231738
https://www.jianshu.com/p/b212afa16f1f