首页 > 技术文章 > java8新特性——时间日期API

wuyx 2018-06-10 21:30 原文

  传统的时间 API 存在线程安全的问题,在多线程开发中必须要上锁,所以 java8 现在为我们提供了一套全新的时间日期 API ,今天进来学习一下java8 的时间日期 API。

 

一、使用 LocalDate、LocalTime、LocalDateTime

  LocalDate、LocalTime、LocalDateTime类的实例是不可变的对象,分别表示使用 ISO-8601 (ISO-8601 日历系统是国际化组织制定的现代化公民的日期和时间的表达法)日历系统的日期、时间、日期和时间。它们提供了简单的日期或时间,并不包含当前时间的时间信息。也不包含与时区相关的信息。

  LocalDate LocalTime LocalDateTime 三个类的使用方式一样,只是代表的不同而已。

  下面就以LocalDateTime作为例子进行示范:

    1.获取当前时间

1     /**
2      * 获取当前时间
3      */
4     @Test
5     public void test1() {
6         LocalDateTime now = LocalDateTime.now();
7     }

    

    2.获取指定时间日期

1     /**
2      * 获取指定时间日期
3      */
4     @Test
5     public void test2() {
6         LocalDateTime now = LocalDateTime.of(2018, 6, 10, 10, 10, 10);
7     }

   

    3.对时间进行加减操作

 1     /**
 2      * 对时间进行加减操作
 3      */
 4     @Test
 5     public void test3() {
 6         LocalDateTime now = LocalDateTime.of(2018, 6, 10, 10, 10, 10);
 7         //加时间
 8         LocalDateTime time1 = now.plusYears(1).plusMonths(2).
 9                 plusDays(3).plusHours(5).plusMinutes(45).
10                 plusSeconds(32);
11         //剪时间
12         LocalDateTime time2 = now.minusYears(1).minusMonths(2).
13                 minusDays(3).minusHours(5).minusMinutes(45).
14                 minusSeconds(32);
15     }

  对旧的时间进行操作之后返回一个新的时间。

    

    4. 获取获取时间的年、月、日

 1     /**
 2      * 获取时间的年、月、日
 3      */
 4     @Test
 5     public void test4() {
 6         LocalDateTime now = LocalDateTime.of(2018, 6, 10, 10, 10, 10);
 7         //获取年
 8         int year = now.getYear();
 9         //获取月
10         Month month = now.getMonth();
11         //获取月的value值
12         int monthValue = now.getMonthValue();
13         //获取在本月的第几天(日)
14         int dayOfMonth = now.getDayOfMonth();
15         //获取在本年的第几天
16         int dayOfYear = now.getDayOfYear();
17         //获取在本周的第几天(星期几)
18         DayOfWeek dayOfWeek = now.getDayOfWeek();
19         //获取小时
20         int hour = now.getHour();
21         //获取分钟
22         int minute = now.getMinute();
23         //获取秒
24         int second = now.getSecond();
25         //获取纳秒
26         int nano = now.getNano();27     }

 

二、使用 Instant : 时间戳(以Unix 元年 : 1970-01-01 00:00:00 到某个时间之间的毫秒数)

  1. 获取系统当前时间

1     /**
2      * 获取当前时间 默认获取 UTC 时区
3      */
4     @Test
5     public void test5() {
6         Instant now = Instant.now();
7     }

  上面时间默认获取到的是 UTC 时区的时间,与中国时间相差8小时,我们可以给它设置偏移量。

1     /**
2      * 获取中国当前时间
3      */
4     @Test
5     public void test6() {
6         Instant now = Instant.now().
7                 atOffset(ZoneOffset.ofHours(8)).toInstant();
8     }

 

  2. 获取当前时间的时间戳

1     /**
2      * 获取中国当前时间戳
3      */
4     @Test
5     public void test7() {
6         long now = Instant.now().
7                 atOffset(ZoneOffset.ofHours(8)).toInstant().toEpochMilli();
8     }

 

三、Duration 计算两个时间之间的间隔

 1     /**
 2      * 获取两个时间之间的间隔
 3      */
 4     @Test
 5     public void test8() {
 6         Instant now1 = Instant.now();
 7         Instant now2 = Instant.now().
 8                 atOffset(ZoneOffset.ofHours(8)).toInstant();
 9         Duration.between(now1, now2);
10         
11         LocalDateTime now3 = LocalDateTime.now();
12         LocalDateTime now4 = LocalDateTime.of(2018, 6, 10, 10, 10, 10);
13         
14         Duration.between(now3, now4);
15     }

 

 

四、Period 计算两个日期之间的间隔

 1     /**
 2      * 获取两个日期之间的间隔
 3      */
 4     @Test
 5     public void test9() {
 6         LocalDate now1 = LocalDate.now();
 7         LocalDate now2 = LocalDate.of(2018, 6, 10);
 8         
 9         Period.between(now1, now2);
10     }

 

五、时间校正器

   TemporalAdjuster:时间矫正器。有时我们可能需要获取一个周末,或者下一个工作日等时间,这里 java8 就为我们提供了一个时间校正器,让我们对时间进行校准。

  TemporalAdjusters:该类通过静态方法提供了大量的常用的TemporalAdjuster的实现供我们使用。

  在localDateTime中,有一个with方法,其中可以让我们去写一TemporalAdjuster接口,而TemporalAdjusters类中,有许多常用的方法,下面就来看看:

 1     /**
 2      * 时间校正器TemporalAdjuster
 3      */
 4     @Test
 5     public void test10() {
 6         LocalDateTime now1 = LocalDateTime.now();
 7         //获取月中 第一天
 8         now1.with(TemporalAdjusters.firstDayOfMonth());
 9         //获取下一年的第一天
10         now1.with(TemporalAdjusters.firstDayOfNextYear());
11         //获取年中第一天
12         now1.with(TemporalAdjusters.lastDayOfYear());
13         //获取月中最后一天
14         now1.with(TemporalAdjusters.lastDayOfMonth());
15         //获取下个星期一
16         now1.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
17         //自定时时间:下一个工作日,因为这里需要一个接口,所以完全可以自定义方法
18         now1.with((e) -> {
19             LocalDateTime now = (LocalDateTime)e; 
20             DayOfWeek dow = now.getDayOfWeek();
21             if (dow.equals(DayOfWeek.FRIDAY)) 
22                 return now.plusDays(3);
23             else if (dow.equals(DayOfWeek.SATURDAY))
24                 return now.plusDays(2);
25             return  now.plusDays(1);
26         });
27     }

 

 六、时间、日期格式化 DateTimeFormatter

   1. 时间转字符串

    在 DateTimeFormatter 中为我们提供了一下多种格式转换方式,我们可以去选择使用。

 1     /**
 2      * The printer and/or parser to use, not null.
 3      */
 4     private final CompositePrinterParser printerParser;
 5     /**
 6      * The locale to use for formatting, not null.
 7      */
 8     private final Locale locale;
 9     /**
10      * The symbols to use for formatting, not null.
11      */
12     private final DecimalStyle decimalStyle;
13     /**
14      * The resolver style to use, not null.
15      */
16     private final ResolverStyle resolverStyle;
17     /**
18      * The fields to use in resolving, null for all fields.
19      */
20     private final Set<TemporalField> resolverFields;
21     /**
22      * The chronology to use for formatting, null for no override.
23      */
24     private final Chronology chrono;
25     /**
26      * The zone to use for formatting, null for no override.
27      */
28     private final ZoneId zone;

 

     当然,我们也可以自定义时间格式,进行转换。

1     /*
2      * 将时间转换为字符串
3      */
4     @Test
5     public void test11() {
6         LocalDate now = LocalDate.now();
7         DateTimeFormatter dtf = DateTimeFormatter.ofPattern("YYYY-MM-DD HH:mm:ss");
8         now.format(dtf);
9     }

 

  2.将字符串转换为时间

1     /*
2      * 将字符串转换为时间
3      */
4     @Test
5     public void test12() {
6         DateTimeFormatter dtf = DateTimeFormatter.ofPattern("YYYY-MM-DD HH:mm:ss");
7         LocalDateTime.parse("2018-06-18 21:45:23", dtf);
8     }

 

推荐阅读