美文网首页
JDK1.8新特性(五):新的日期时间 API

JDK1.8新特性(五):新的日期时间 API

作者: CoderLucas | 来源:发表于2020-08-18 21:46 被阅读0次

    JDK1.8系列文章

    Java 8 在 java.time 包中包含一个全新的日期和时间 API。新的 Date API 与 Joda-Time 库具有可比性,但是并不相同。下面的示例涵盖了这个新API的最重要部分。

    在《阿里巴巴 Java 开发手册》中有提到,SimpleDateFormat 是线程不安全的类,一般不要定义为static变量,如果定义为 static,必须加锁,或者使用 DateUtils 工具类。

    正例:注意线程安全,使用 DateUtils。亦推荐如下处理:

    private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {  
        @Override
        protected DateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd");
    } };
    

    如果是 JDK8 的应用,可以使用 Instant 代替 Date,LocalDateTime 代替 Calendar, DateTimeFormatter 代替 Simpledateformatter,官方给出的解释:simple beautiful strong immutable thread-safe。

    一、Clock

    Clock 提供对访问当前日期和时间的方法。Clocks 与时区相关,可以用 System.currentTimeMillis() 来获取当前的微秒数。 某一个特定的时间点也可以使用 Instant 类来表示,Instant 类也可以用来创建旧版本的 java.util.Date 对象。

    Clock clock = Clock.systemDefaultZone();
    long millis = clock.millis();
    
    Instant instant = clock.instant();
    Date legacyDate = Date.from(instant);   // legacy java.util.Date
    

    二、Timezones

    时区由 ZoneId 表示,可以通过静态工厂方法轻松访问它们。时区定义了偏移量,这对于在瞬间与本地日期和时间之间进行转换很重要。

    System.out.println(ZoneId.getAvailableZoneIds());
    // prints all available timezone ids
    
    ZoneId zone1 = ZoneId.of("Europe/Berlin");
    ZoneId zone2 = ZoneId.of("Brazil/East");
    System.out.println(zone1.getRules());
    System.out.println(zone2.getRules());
    
    // ZoneRules[currentStandardOffset=+01:00]
    // ZoneRules[currentStandardOffset=-03:00]
    

    三、LocalTime

    LocalTime 表示没有时区的时间,例如晚上10点或17:30:15。以下示例为上面定义的时区创建两个本地时间。然后,我们比较两个时间,并计算两个时间之间的小时和分钟差异。

    LocalTime now1 = LocalTime.now(zone1);
    LocalTime now2 = LocalTime.now(zone2);
    
    System.out.println(now1.isBefore(now2));  // false
    
    long hoursBetween = ChronoUnit.HOURS.between(now1, now2);
    long minutesBetween = ChronoUnit.MINUTES.between(now1, now2);
    
    System.out.println(hoursBetween);       // -3
    System.out.println(minutesBetween);     // -239
    

    LocalTime 带有各种工厂方法来简化新实例的创建,包括时间字符串的解析。

    LocalTime late = LocalTime.of(23, 59, 59);
    System.out.println(late);       // 23:59:59
    
    DateTimeFormatter germanFormatter =
        DateTimeFormatter
            .ofLocalizedTime(FormatStyle.SHORT)
            .withLocale(Locale.GERMAN);
    
    LocalTime leetTime = LocalTime.parse("13:37", germanFormatter);
    System.out.println(leetTime);   // 13:37
    

    四、LocalDate

    LocalDate 代表一个不同的日期,例如2014-03-11。它是不可变的,并且完全类似于 LocalTime。该示例演示了如何通过增加或减去天,月或年来计算新日期。请记住,每种操作都会返回一个新实例。

    LocalDate today = LocalDate.now();
    LocalDate tomorrow = today.plus(1, ChronoUnit.DAYS);
    LocalDate yesterday = tomorrow.minusDays(2);
    
    LocalDate independenceDay = LocalDate.of(2014, Month.JULY, 4);
    DayOfWeek dayOfWeek = independenceDay.getDayOfWeek();
    System.out.println(dayOfWeek);    // FRIDAY
    

    从字符串中解析 LocalDate 就像解析 LocalTime 一样简单:

    DateTimeFormatter germanFormatter =
        DateTimeFormatter
            .ofLocalizedDate(FormatStyle.MEDIUM)
            .withLocale(Locale.GERMAN);
    
    LocalDate xmas = LocalDate.parse("24.12.2014", germanFormatter);
    System.out.println(xmas);   // 2014-12-24
    

    五、LocalDateTime

    LocalDateTime 表示日期时间。如上所述,它将日期和时间组合为一个实例。 LocalDateTime 是不可变的,其工作方式类似于 LocalTime 和 LocalDate 。我们可以利用方法从日期时间检索某些字段:

    LocalDateTime sylvester = LocalDateTime.of(2014, Month.DECEMBER, 31, 23, 59, 59);
    
    DayOfWeek dayOfWeek = sylvester.getDayOfWeek();
    System.out.println(dayOfWeek);      // WEDNESDAY
    
    Month month = sylvester.getMonth();
    System.out.println(month);          // DECEMBER
    
    long minuteOfDay = sylvester.getLong(ChronoField.MINUTE_OF_DAY);
    System.out.println(minuteOfDay);    // 1439
    

    利用时区信息,可以将其转换为一个时间点Instant对象。Instant时间点对象可以轻松地转换为 java.util.Date 类型的日期。

    Instant instant = sylvester
            .atZone(ZoneId.systemDefault())
            .toInstant();
    
    Date legacyDate = Date.from(instant);
    System.out.println(legacyDate);     // Wed Dec 31 23:59:59 CET 2014
    

    格式化日期时间就像格式化日期或时间一样。可以使用自定义模式创建格式化程序,而不是使用预定义格式。

    DateTimeFormatter formatter =
        DateTimeFormatter
            .ofPattern("MMM dd, yyyy - HH:mm");
    
    LocalDateTime parsed = LocalDateTime.parse("Nov 03, 2014 - 07:13", formatter);
    String string = formatter.format(parsed);
    System.out.println(string);     // Nov 03, 2014 - 07:13
    

    和 java.text.NumberFormat 不一样,新版的 DateTimeFormatter 是不可变的并且是线程安全的。

    六、公众号

    如果大家想要第一时间看到我更新的 Java 方向学习文章,可以关注一下公众号【Lucas的咖啡店】。所有学习文章公众号首发,请各位大大扫码关注一下哦!

    Java 8 新特性学习视频请关注公众号,私信【Java8】即可免费无套路获取学习视频。

    相关文章

      网友评论

          本文标题:JDK1.8新特性(五):新的日期时间 API

          本文链接:https://www.haomeiwen.com/subject/lacljktx.html