Java8全新日期API探秘

综述

新的API:java.time,由5个包组成:

  • java.time – 包含值对象的基础包
  • java.time.chrono – 提供对不同的日历系统的访问
  • java.time.format – 格式化和解析时间和日期
  • java.time.temporal – 包括底层框架和扩展特性
  • java.time.zone – 包含时区支持的类

大多数开发者只会用到基础和format包,也可能会用到temporal包。因此,尽管有68个新的公开类型,大多数开发者,大概,将只会用到其中的三分之一。

核心思路

挺意外。团队一堆人在研究并实现DDD,没想到身边的工具类就使用到了。

  • 不可改变值的类。 一个严重的问题是,对于Java中已经存在的格式化处理类(Formatter)不是线程安全的。这使开发人员在日常开发中需要编写线程安全的日期处理代码变得很麻烦。新的API保证所有的核心类中的值是不可变的,避免了并发情况下带来的不必要的问题。

  • 领域驱动设计。 新的API模型可以精确的表示出Date和Time的差异性。在以前的Java库中这一点就表现的非常差。比如,java.util.Date他表示一个时间点,从Unix时代开始就是以毫秒数的形式保存,但是你调用它的toString方法时,结果却显示它是有时区概念的,这就容易让开发者产生歧义。领域驱动设计的重点是从长远好处出发且简单易懂, 当你需要把你以前的处理时间的模块代码移植到Java8上时你就需要考虑一下领域模型的设计了。

  • 区域化时间体系。 新的API允许人们在时区不同的时间体系下使用。比如日本或者泰国,他们不必要遵循 ISO-8601。新API为大多数开发者减少了很多额外的负担,我们只需要使用标准的时间日期API。

使用举例

使用方面,我自己综合了网络上面的很多文章,总结了以下几个需要用到的(这里主要使用LocalDateTime作为举例):

  • Date转成LocalDateTime
  • LocalDateTime转成Date
  • 时间戳转换成LocalDate
  • 时间戳格式化成可读日期
  • Date格式化成可读日期
public class DateUtil {

    private DateUtil() {
    }

    public static String timestamp2String(Long timestamp, String formatter) {
        LocalDateTime localDateTime = date2LocalDateTime(timestamp);
        return localDateTime.format(DateTimeFormatter.ofPattern(formatter));
    }

    public static String date2String(Date date,String formatter){
        LocalDateTime localDateTime = date2LocalDateTime(date);
        return localDateTime.format(DateTimeFormatter.ofPattern(formatter));
    }

    public static String localDateTime2String(LocalDateTime localDateTime,String formatter){
        return localDateTime.format(DateTimeFormatter.ofPattern(formatter));
    }

    public static LocalDateTime date2LocalDateTime(Date date) {
        Instant instant = date.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();
        LocalDateTime localDate = instant.atZone(zoneId).toLocalDateTime();
        return localDate;
    }

    public static Date localDateTime2Date(LocalDateTime localDateTime){
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zdt = localDateTime.atZone(zoneId);
        return Date.from(zdt.toInstant());
    }

   public static long localDateTime2Timestamp(LocalDateTime localDateTime){
        Timestamp timestamp = Timestamp.valueOf(localDateTime);
        return timestamp.getTime();
    }

    public static LocalDateTime date2LocalDateTime(Long timestamp) {
        Instant instant = Instant.ofEpochMilli(timestamp);
        ZoneId zoneId = ZoneId.systemDefault();
        LocalDateTime localDate = instant.atZone(zoneId).toLocalDateTime();
        return localDate;
    }

}

其他的一些使用日常

另外,日常中,我们可能还会使用一些方式,我都总结一下

  • 获取当前的时间:LocalDateTime.now()

  • 获取当前的时间戳:Instant.ofEpochMilli(System.currentTimeMillis())

  • 获取当前所在月份的第一天:LocalDateTime.now().with(TemporalAdjusters.firstDayOfMonth())

  • 获取当前所在月份的最后一天:LocalDateTime.now().with(TemporalAdjusters.lastDayOfMonth())

  • 将一个字符串的时间格式化成LocalDateTime: LocalDateTime.parse("2012-09-01 12:12:12",DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))

猜你喜欢

转载自my.oschina.net/UBW/blog/1620574