java8新的时间日期库

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_26482855/article/details/82050212

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异常。

猜你喜欢

转载自blog.csdn.net/qq_26482855/article/details/82050212
今日推荐