java8新的时间日期库

java8是如何处理时间及日期的

一、简介

java8中的java.time包中的类是不可变且线程安全的。新的时间及日期API位于java.time中,下面是一些关键类的简单介绍:

●Instant——它代表的是时间戳

●LocalDate——不包含具体时间的日期,比如2014-01-14。它可以用来存储生日,周年纪念日,入职日期等。

●LocalTime——它代表的是不含日期的时间

●LocalDateTime——它包含了日期及时间,不过还是没有偏移信息或者说时区。

●ZonedDateTime——这是一个包含时区的完整的日期时间,偏移量是以UTC/格林威治时间为基准的。

二、实用实例

1、日期的获取

java8中有个叫LocalDate的类,能用来表示今天的日期。这个类与java.util.Date略有不同,因为它只包含日期,没有时间。

LocalDate是用来表示无时间的日期,他有一个plus()方法可以用来增加日,星期,月,ChronoUnit则用来表示时间单位,LocalDate也是不可变的,因此任何修改操作都会返回一个新的实例

    public static void main(String[] args) {
        LocalDate today = LocalDate.now();
        System.out.println("今天的日期是:"+today);
        int year = today.getYear();
        int monthValue = today.getMonthValue();
        int dayOfMonth = today.getDayOfMonth();
        System.out.println("今天的日期是:"+year+"年"+monthValue+"月"+dayOfMonth+"日");
        LocalDate years = today.plusYears(1);
        System.out.println("明年的今天是:"+years);
        LocalDate months = today.plusMonths(2);
        System.out.println("两个月后是:"+months);
        LocalDate minusMonths = today.minusMonths(2);
        System.out.println("两个月前是:"+minusMonths);
        LocalDate localDate = LocalDate.of(2018, 8, 25);//月份从1开始,与之前版本的api不同
        System.out.println("指定的日期是:"+localDate);
    }

输出:

今天的日期是:2018-08-24

今天的日期是:2018年8月24日

明年的今天是:2019-08-24

两个月后是:2018-10-24

两个月前是:2018-06-24

指定的日期是:2018-08-25

2、日期的比较

LocalDate重写了equals方法来进行日期的比较,如下所示

    public static void main(String[] args) {
        LocalDate today = LocalDate.now();
        System.out.println("今天是:"+today);
        boolean leapYear = today.isLeapYear();
        System.out.println("今年是闰年么:"+leapYear);
        LocalDate localDate = LocalDate.of(2018, 8, 25);
        System.out.println("今天是2018-08-25么:"+localDate.equals(today));
        boolean before = today.isBefore(localDate);
        System.out.println("今天在2018-08-25之前么:"+before);
        Period between = Period.between(today, localDate);
        int days = between.getDays();
        System.out.println("今天与2018-08-25相差几天:"+days);
    }

输出:

今天是:2018-08-24

今年是闰年么:false

今天是2018-08-25么:false

今天在2018-08-25之前么:true

今天与2018-08-25相差几天:1

3、日期的重复事件,比如账单日、生日

在java中还有一个与时间日期相关的任务就是检查重复事件,比如每月的账单日、生日

如何在java中判断是否是某个节日或者重复事件,使用MonthDay类。这个类由月日组合,不包含年信息,可以用来代表每年重复出现的一些日期或其他组合。他和新的日期库中的其他类一样也都是不可变且线程安全的,并且它还是一个值类

    public static void main(String[] args) {
        //LocalDate today = LocalDate.now();
        LocalDate dayOfBirth = LocalDate.of(1991, 8, 24);
        MonthDay birthDay = MonthDay.of(dayOfBirth.getMonth(), dayOfBirth.getDayOfMonth());
        MonthDay now = MonthDay.now();
        if(now.equals(birthDay)){
            System.out.println("今天是你的生日");
        }else {
            System.out.println("今天不是你的生日");
        }
    }

输出:

今天是你的生日

4、时间的获取

这个与第一个例子获取当前日期非常相似,这里用的是LocalTime类,默认的格式是hh:mm:ss:nnn

很多时候需要对时间进行操作,比如加一个小时来计算之后的时间,java8提供了更方便的方法 如plusHours,这些方法返回的是一个新的LocalTime实例的引用,因为LocalTime是不可变的

    public static void main(String[] args) {
        LocalTime now = LocalTime.now();
        System.out.println("当前时间是:"+now);
        LocalTime plusHours = now.plusHours(2);
        System.out.println("两小时后是:"+plusHours);
        LocalTime minusHours = now.minusHours(2);
        System.out.println("两个小时前是:"+minusHours);
        LocalTime plusMinutes = now.plusMinutes(40);
        System.out.println("40分钟后是:"+plusMinutes);
    }

输出:

当前时间是:15:14:34.650

两小时后是:17:14:34.650

两个小时前是:13:14:34.650

40分钟后是:15:54:34.650

5、时钟的使用

java8自带了Clock类,可以用来获取某个时区下(所以对时区是敏感的)当前的瞬时时间、日期。用来代替System.currentTimelnMillis()与TimeZone.getDefault()方法

    public static void main(String[] args) {
        Clock systemDefaultZone = Clock.systemDefaultZone();
        System.out.println("systemDefaultZone:"+systemDefaultZone);
        Clock systemUTC = Clock.systemUTC();
        System.out.println("systemUTC:"+systemUTC);
        //获取时间戳
        long currentTimeMillis = System.currentTimeMillis();
        System.out.println(currentTimeMillis);
        long epochMilli = Instant.now().toEpochMilli();
        System.out.println(epochMilli);
    }

输出:

systemDefaultZone:SystemClock[Asia/Shanghai]

systemUTC:SystemClock[Z]

1535095670978

1535095670978

6、不同时区的处理

java8中不仅将日期和时间进行了分离,同时还有时区。比如ZonId代表的是某个特定时区,ZonedDateTime代表带时区的时间,等同于以前的GregorianCalendar类。使用该类,可以将本地时间转换成另一个时区中的对应时间。

    public static void main(String[] args) {
        LocalDateTime now = LocalDateTime.now();
        ZoneId act = ZoneId.of(ZoneId.SHORT_IDS.get("CST"));//美国芝加哥,属于西五区
        ZonedDateTime zonedDateTime = ZonedDateTime.of(now, act);
        System.out.println("zonedDateTime:"+zonedDateTime);
    }

输出:

zonedDateTime:2018-08-24T15:36:42.265-05:00[America/Chicago]

7、带时区的日期与时间

在java8中,可以使用ZoneOffset来代表某个时区,可以使用它的静态方法ZoneOffset.of()方法来获取对应的时区,只要获得了这个偏移量,就可以用这个偏移量和LocalDateTime创建一个新的OffsetDateTime

    public static void main(String[] args) {
        LocalDateTime now = LocalDateTime.now();
        System.out.println("now:"+now);
        ZoneOffset zoneOffset = ZoneOffset.of("+02:30");
        OffsetDateTime offsetDateTime = OffsetDateTime.of(now, zoneOffset);
        System.out.println("offsetDateTime:"+offsetDateTime);
    }

输出:

now:2018-08-24T16:23:13.667

offsetDateTime:2018-08-24T16:23:13.667+02:30

8,日期的解析/格式化

在java8之前,时间日期的格式化非常麻烦,经常使用SimpleDateFormat来进行格式化,但是SimpleDateFormat并不是线程安全的。在java8中,引入了一个全新的线程安全的日期与时间格式器。并且预定义好了格式。

    public static void main(String[] args) {
        LocalDateTime now = LocalDateTime.now();
        System.out.println("now:"+now);
        LocalDate localDate = now.toLocalDate();
        LocalTime localTime = now.toLocalTime();
        String format = now.format(DateTimeFormatter.ISO_DATE_TIME);
        System.out.println("ISO_DATE_TIME:"+format);
        format = now.format(DateTimeFormatter.ISO_DATE);
        System.out.println("ISO_DATE:"+format);
        format = now.format(DateTimeFormatter.ISO_TIME);
        System.out.println("ISO_TIME:"+format);

        String dateTimeString = "2018-08-24 16:54:32";
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime localDateTime = LocalDateTime.parse(dateTimeString, dateTimeFormatter);
        System.out.println("localDateTime"+localDateTime);
        format = now.format(dateTimeFormatter);
        System.out.println("format:"+format);
    }

输出:

now:2018-08-24T17:01:12.553

ISO_DATE_TIME:2018-08-24T17:01:12.553

ISO_DATE:2018-08-24

ISO_TIME:17:01:12.553

localDateTime2018-08-24T16:54:32

format:2018-08-24 17:01:12

三、使用中需要注意的关键点:

●Instant 它代表的是时间戳

●LocalDate 它表示的是不带时间的日期

●LocalTime - 它表示的是不带日期的时间

●LocalDateTime - 它包含了时间与日期,不过没有带时区的偏移量

●ZonedDateTime - 这是一个带时区的完整时间,它根据UTC/格林威治时间来进行时区调整

●OffsetDateTime类实际上包含了LocalDateTime与ZoneOffset。它用来表示一个包含格林威治时间偏移量(+/-小时:分,比如+06:00或者 -08:00)的完整的日期(年月日)及时间(时分秒,纳秒)。

●DateTimeFormatter类用于在Java中进行日期的格式化与解析。与SimpleDateFormat不同,它是不可变且线程安全的,如果需要的话,可以赋值给一个静态变量。DateTimeFormatter类提供了许多预定义的格式器,你也可以自定义自己想要的格式。当然了,根据约定,它还有一个parse()方法是用于将字符串转换成日期的,如果转换期间出现任何错误,它会抛出DateTimeParseException异常。类似的,DateFormatter类也有一个用于格式化日期的format()方法,它出错的话则会抛出DateTimeException异常。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值