对Java8新的日期时间类的学习

Posted 盛夏群岛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了对Java8新的日期时间类的学习相关的知识,希望对你有一定的参考价值。

示例11 在Java中如何判断某个日期是在另一个日期的前面还是后面

这也是实际项目中常见的一个任务。你怎么判断某个日期是在另一个日期的前面还是后面,或者正好相等呢?在Java 8中,LocalDate类有一个isBefore()和isAfter()方法可以用来比较两个日期。如果调用方法的那个日期比给定的日期要早的话,isBefore()方法会返回true。

        LocalDate today = LocalDate.now();
        LocalDate tomorrow = LocalDate.of(2020, 2, 13);
        if(tomorrow.isAfter(today)){
            System.out.println("Tomorrow comes after today");
        }
        LocalDate yesterday = today.minus(1, ChronoUnit.DAYS);
        if(yesterday.isBefore(today)){
            System.out.println("Yesterday is day before today");
        }

/*运行结果*/
Tomorrow comes after today
Yesterday is day before today

可以看到在Java 8中进行日期比较非常简单。不需要再用像Calendar这样的另一个类来完成类似的任务了。

示例12 在Java 8中处理不同的时区

Java 8不仅将日期和时间进行了分离,同时还有时区。现在已经有好几组与时区相关的类了,比如ZonId代表的是某个特定的时区,而ZonedDateTime代表的是带时区的时间。它等同于Java 8以前的GregorianCalendar类。使用这个类,你可以将本地时间转换成另一个时区中的对应时间,比如下面这个例子:

        LocalDateTime localtDateAndTime = LocalDateTime.now();
        ZonedDateTime dateAndTimeInParis = ZonedDateTime.of(localtDateAndTime,ZoneId.of("Europe/Paris"));
        System.out.println("Current date and time in a particular timezone : " + dateAndTimeInParis);

Current date and time in a particular timezone : 2020-02-12T11:12:27.161+01:00[Europe/Paris]

示例13 如何表示固定的日期,比如信用卡过期时间

正如MonthDay表示的是某个重复出现的日子的,YearMonth又是另一个组合,它代表的是像信用卡还款日,定期存款到期日,options到期日这类的日期。你可以用这个类来找出那个月有多少天,lengthOfMonth()这个方法返回的是这个YearMonth实例有多少天,这对于检查2月到底是28天还是29天可是非常有用的。

        YearMonth currentYearMonth = YearMonth.now();
        System.out.printf("Days in month year %s: %d%n", currentYearMonth, currentYearMonth.lengthOfMonth());
        YearMonth creditCardExpiry = YearMonth.of(2020, Month.AUGUST);
        System.out.printf("Your credit card expires on %s %n", creditCardExpiry);

Days in month year 2020-02: 29
Your credit card expires on 2020-08 

示例14 如何在Java 8中检查闰年

这并没什么复杂的,LocalDate类有一个isLeapYear()的方法能够返回当前LocalDate对应的那年是否是闰年。如果你还想重复造轮子的话,可以看下这段代码,这是纯用Java编写的判断某年是否是闰年的逻辑

        LocalDate today = LocalDate.now();
        if(today.isLeapYear()){
            System.out.println("This year is Leap year");
        }else {
            System.out.println("2014 is not a Leap year");
        }
    }

This year is Leap year

示例15 两个日期之间包含多少天,多少个月

还有一个常见的任务就是计算两个给定的日期之间包含多少天,多少周或者多少年。你可以用java.time.Period类来完成这个功能。在下面这个例子中,我们将计算当前日期与将来的一个日期之前一共隔着几个月。

 LocalDate today = LocalDate.now();
        LocalDate java8Release = LocalDate.of(2014, Month.MARCH, 14);
        Period periodfromLastJavaRelease =
                Period.between(java8Release,today);
        System.out.println("Months left between today and Java 8 release : "
                + periodfromLastJavaRelease.getYears()+"	"+
                periodfromLastJavaRelease.getMonths()+"	"+
                periodfromLastJavaRelease.getDays()
                );


Months left between today and Java 8 release : 5 10 29,5年10个月29天

 

 

示例16 带时区偏移量的日期与时间

在Java 8里面,你可以用ZoneOffset类来代表某个时区,比如印度是GMT或者UTC5:30,你可以使用它的静态方法ZoneOffset.of()方法来获取对应的时区。只要获取到了这个偏移量,你就可以拿LocalDateTime和这个偏移量创建出一个OffsetDateTime。

        LocalDateTime datetime = LocalDateTime.of(2014, Month.JANUARY, 14, 19, 30);
        ZoneOffset offset = ZoneOffset.of("+05:30");//偏移量
        OffsetDateTime date = OffsetDateTime.of(datetime, offset);//偏移量下的时间
        System.out.println("Date and Time with timezone offset in Java : " + date);
    }

Date and Time with timezone offset in Java : 2014-01-14T19:30+05:30

可以看到现在时间日期与时区是关联上了。还有一点就是,OffSetDateTime主要是给机器来理解的,如果是给人看的,可以使用ZoneDateTime类

示例17 在Java 8中如何获取当前时间戳

如果你还记得在Java 8前是如何获取当前时间戳的,那现在这简直就是小菜一碟了。Instant类有一个静态的工厂方法now()可以返回当前时间戳,如下:

        Instant timestamp = Instant.now();
        System.out.println("What is value of this instant " + timestamp);

What is value of this instant 2020-02-12T03:48:18.306Z

可以看出,当前时间戳是包含日期与时间的,与java.util.Date很类似,事实上Instant就是Java 8前的Date,你可以使用这两个类中的方法来在这两个类型之间进行转换,比如Date.from(Instant)是用来将Instant转换成java.util.Date的,而Date.toInstant()是将Date转换成Instant的

示例18 如何在Java 8中使用预定义的格式器来对日期进行解析/格式化

在Java 8之前,时间日期的格式化可是个技术活,我们的好伙伴SimpleDateFormat并不是线程安全的,而如果用作本地变量来格式化的话又显得有些笨重。多亏了线程本地变量,这使得它在多线程环境下也算有了用武之地,但Java维持这一状态也有很长一段时间了。这次它引入了一个全新的线程安全的日期与时间格式器。它还自带了一些预定义好的格式器,包含了常用的日期格式。比如说,本例 中我们就用了预定义的BASICISODATE格式,它会将2014年2月14日格式化成20140114。

String dayAfterTommorrow = "20140116";
        LocalDate formatted = LocalDate.parse(dayAfterTommorrow,
                DateTimeFormatter.BASIC_ISO_DATE);
        System.out.printf("Date generated from String %s is %s %n", dayAfterTommorrow, formatted);

Date generated from String 20140116 is 2014-01-16 
    

你可以看到生成的日期与指定字符串的值是匹配的,就是日期格式上略有不同。

示例19 如何在Java中使用自定义的格式器来解析日期

在上例中,我们使用了内建的时间日期格式器来解析日期字符串。当然了,预定义的格式器的确不错但有时候你可能还是需要使用自定义的日期格式,这个时候你就得自己去创建一个自定义的日期格式器实例了。下面这个例子中的日期格式是"MMM dd yyyy"。你可以给DateTimeFormatter的ofPattern静态方法()传入任何的模式,它会返回一个实例,这个模式的字面量与前例中是相同的。比如说M还是代表月,而m仍是分。无效的模式会抛出DateTimeParseException异常,但如果是逻辑上的错误比如说该用M的时候用成m,这样就没办法了。

     String goodFriday = "2014-01-01";
        try {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            LocalDate holiday = LocalDate.parse(goodFriday, formatter);
            System.out.printf("Successfully parsed String %s, date is %s%n", goodFriday, holiday);
        } catch (DateTimeParseException ex) {
            System.out.printf("%s is not parsable!%n", goodFriday);
            ex.printStackTrace();
        }

Successfully parsed String 2014-01-01, date is 2014-01-01

示例20 如何在Java 8中对日期进行格式化,转换成字符串

在上两个例子中,尽管我们用到了DateTimeFormatter类但我们主要是进行日期字符串的解析。在这个例子中我们要做的事情正好相反。这里我们有一个LocalDateTime类的实例,我们要将它转换成一个格式化好的日期串。这是目前为止Java中将日期转换成字符串最简单便捷的方式了。下面这个例子将会返回一个格式化好的字符串。与前例相同的是,我们仍需使用指定的模式串去创建一个DateTimeFormatter类的实例,但调用的并不是LocalDate类的parse方法,而是它的format()方法。这个方法会返回一个代表当前日期的字符串,对应的模式就是传入的DateTimeFormatter实例中所定义好的。

        LocalDateTime arrivalDate = LocalDateTime.now();
        try {
            DateTimeFormatter format = DateTimeFormatter.ofPattern("MMM dd yyyy hh:mm a");
            String landing = arrivalDate.format(format);
            System.out.printf("Arriving at : %s %n", landing);
        } catch (DateTimeException ex) {
            System.out.printf("%s can‘t be formatted!%n", arrivalDate);
            ex.printStackTrace();
        }

Arriving at : 二月 12 2020 12:09 下午 

可以看到,当前时间是用给定的"MMM dd yyyy hh:mm a"模式来表示的,它包含了三个字母表示的月份以及用AM及PM来表示的时间。

 

以上是关于对Java8新的日期时间类的学习的主要内容,如果未能解决你的问题,请参考以下文章

java8新特性学习六(新时间日期API)

java8新特性学习六(新时间日期API)

Java8 时间日期类操作

Java8新的日期API LocalDate, LocalTime

20191227 Java8 日期时间API

java8 - 新的时间日期API示例