Java8新特性——新时间日期API

Java8新特性——新时间日期API

在Java8之前,时间日期API存在线程安全的问题,多线程情况下需要加锁,并且使用起来也比较不方便。Java8为我们提供了新的时间日期API。这篇文章,我们一起来使用下。

1. 使用LocalDate、LocalTime、LocalDateTime

LocalDateLocalTimeLocalDateTime类的实例是不可变的对象,分别表示使用ISO-8601日历系统的日期、时间、日期和时间。它们提供了简单的日期或时间,并不包含当前的时间信息。也不包含与时区相关的信息。

注: ISO-8601日历系统是国际标准化组织制定的现代公民的日期和时间的表示法

接下来,我们就以LocalDateTime为例,其它2个类使用方法一样,这里不再赘述。

  1. 获取当前时间:
    /**
     * 获取当前时间
     */
    @Test
    public void test1() {
        LocalDateTime now = LocalDateTime.now();
        System.out.println(now);
    }

Output:

2019-05-30T21:36:49.269
  1. 根据字符串创建指定日期对象
    /**
     * 创建指定日期
     */
    @Test
    public void test2(){
        LocalDateTime dateTime = LocalDateTime.of(2019, 5, 30, 21, 41, 10);
        System.out.println(dateTime);
    }

Output:

2019-05-30T21:41:10
  1. 日期加减运算
    /**
     * 日期加减运算
     */
    @Test
    public void test3(){
        LocalDateTime now = LocalDateTime.of(2019, 5, 30, 21, 45, 10);
        LocalDateTime plusTime = now.plusYears(1) // 加一年
                .plusMonths(2) // 加2月
                .plusDays(3) // 加三天
                .plusHours(4) // 加4小时
                .plusMinutes(5) // 加5分钟
                .plusSeconds(6); // 加6秒
        System.out.println(plusTime);
        LocalDateTime minusTime = now.minusYears(1) // 减一年
                .minusMonths(2) // 减2月
                .minusDays(3) // 减 3天
                .minusHours(4) // 减4小时
                .minusMinutes(5) // 减5分钟
                .minusSeconds(6); // 减6秒
        System.out.println(minusTime);
    }

Output:

2020-08-03T01:50:16
2018-03-27T17:40:04
  1. 指定年份、月份、天数返回新的日期
    /**
     * 修改月份天数、月份、年份为指定值返回新的LocalDate对象
     */
    @Test
    public void test4(){
        LocalDate today = LocalDate.of(2019, 5, 30);
        LocalDate date = today.withYear(2020) // 将年份修改为2010年
                .withMonth(10) // 修改月份为10月
                .withDayOfMonth(24); // 修改月份天数为24号
        System.out.println(date);
    }

Output:

2020-10-24
  1. 获取日期年月日等
    /**
     * 获取日期年月日等
     */
    @Test
    public void test5(){
        LocalDate today = LocalDate.of(2019, 5, 30);
        System.out.println(today.getDayOfMonth()); // 月份天数(1-31)
        System.out.println(today.getDayOfYear()); // 年份天数(1-366)
        System.out.println(today.getDayOfWeek()); // 星期几(返回一个DayOfWeek枚举值)
        System.out.println(today.getMonth()); // 月份,返回一个Month枚举值
        System.out.println(today.getMonthValue()); // 返回具体的月份值(1-12)
        System.out.println(today.getYear()); // 返回年份的具体值,如2019
    }

Output:

30
150
THURSDAY
MAY
5
2019
  1. until获取2个日期间的Period对象或者指定的ChronoUnit的数字
    /**
     * until获取2个日期间的Period对象或者指定的ChronoUnit的数字
     */
    @Test
    public void test6(){
        LocalDate date = LocalDate.of(2018, 10, 24);
        LocalDate today = LocalDate.of(2019, 5, 30);
        Period period = date.until(today);
        System.out.println(period);

        long until = date.until(LocalDate.of(2018, 5, 21), ChronoUnit.MONTHS); // 2个日期间,按月相差多少
        System.out.println(until);
    }

Output:

P7M6D // 相差7个月6天
-5 // 小5个月
  1. 比较2个LocalDate前后
    /**
     * 比较2个LocalDate前后
     */
    @Test
    public void test7(){
        LocalDate date1 = LocalDate.of(2018, 5, 21);
        LocalDate date2 = LocalDate.of(2018, 10, 24);
        System.out.println(date1.isBefore(date2)); // date1在date2之前?返回true
        System.out.println(date2.isAfter(date1)); // date2在date1之后?返回true
    }
  1. 判断是否闰年
    /**
     * 判断是否闰年
     */
    @Test
    public void test8(){
        LocalDate date1 = LocalDate.of(2020, 5, 21);
        LocalDate date2 = LocalDate.of(2019, 5, 30);
        System.out.println(date1.isLeapYear()); // true
        System.out.println(date2.isLeapYear()); // false
    }

2. Instant 时间戳

用于“时间戳”的运算。它是以Unix元年(传统的设定为UTC时区1970年1月1日午夜时分)开始所经历的描述进行运算

  1. 获取当前时间戳
    /**
     * Instant获取当前时间戳
     */
    @Test
    public void test9(){
        long milli = Instant.now().toEpochMilli();
        System.out.println(milli);
        System.out.println(System.currentTimeMillis());
    }

Output:

1559226655246
1559226655246

3. Duration 和 Period

  1. Duration:用于计算两个“时间”间隔
    /**
     * Duration计算2个时间差
     */
    @Test
    public void test10(){
        LocalDateTime now = LocalDateTime.of(2019, 5, 30, 22, 32, 10);
        LocalDateTime time = LocalDateTime.of(2019, 5, 30, 10, 20, 11);
        Duration duration = Duration.between(time, now);
        System.out.println(duration);
    }

Output:

PT12H11M59S // 相差12小时11分钟59秒
  1. Period:用于计算两个“日期”间隔
    /**
     * 计算2个LocalDate之间差
     */
    @Test
    public void test11(){
        LocalDate today = LocalDate.of(2019, 5, 30);
        LocalDate date = LocalDate.of(2018, 3, 27);
        Period period = Period.between(date, today);
        System.out.println(period);
    }

Output:

P1Y2M3D // 相差1年2月3天

4. 日期的操纵

TemporalAdjuster : 时间校正器。有时我们可能需要获取例如:将日期调整到“下个周日”等操作。
TemporalAdjusters : 该类通过静态方法提供了大量的常用 TemporalAdjuster 的实现。

    /**
     * 下一个周五
     */
    @Test
    public void test12(){
        LocalDate nextFri = LocalDate.now().with(TemporalAdjusters.next(DayOfWeek.FRIDAY));
        System.out.println(nextFri);
    }

5. 解析与格式化

ava.time.format.DateTimeFormatter 类:该类提供了三种格式化方法:

  • 预定义的标准格式
/**
     * The printer and/or parser to use, not null.
     */
    private final CompositePrinterParser printerParser;
    /**
     * The locale to use for formatting, not null.
     */
    private final Locale locale;
    /**
     * The symbols to use for formatting, not null.
     */
    private final DecimalStyle decimalStyle;
    /**
     * The resolver style to use, not null.
     */
    private final ResolverStyle resolverStyle;
    /**
     * The fields to use in resolving, null for all fields.
     */
    private final Set<TemporalField> resolverFields;
    /**
     * The chronology to use for formatting, null for no override.
     */
    private final Chronology chrono;
    /**
     * The zone to use for formatting, null for no override.
     */
    private final ZoneId zone;
  • 语言环境相关的格式
  • 自定义的格式
    /**
     * 自定义格式化日期
     */
    @Test
    public void test13(){
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd HH:mm:ss");
        String time = now.format(dtf);
        System.out.println(time);

        LocalDateTime dateTime = LocalDateTime.parse("20181024 20:21:22", dtf);
        System.out.println(dateTime);
    }

Output:

20190530 22:49:48
2018-10-24T20:21:22

6. 时区的处理

Java8 中加入了对时区的支持,带时区的时间为分别为:
ZonedDate、 ZonedTime、 ZonedDateTime
其中每个时区都对应着 ID,地区ID都为 “{区域}/{城市}”的格式
例如 : Asia/Shanghai 等
ZoneId:该类中包含了所有的时区信息
getAvailableZoneIds() : 可以获取所有时区时区信息
of(id) : 用指定的时区信息获取 ZoneId 对象

7. 与传统日期处理的转换

To 遗留类 From 遗留类
java.time.Instant java.util.Date Date.from(instant) date.toInstant()
java.time.Instant java.sql.Timestamp Timestamp.from(instant) timestamp.toInstant()
java.time.ZonedDateTime java.util.GregorianCalendar GregorianCalendar.from(zonedDateTim e) cal.toZonedDateTime()
java.time.LocalDate java.sql.Time Date.valueOf(localDate) date.toLocalDate()
java.time.LocalTime java.sql.Time Date.valueOf(localDate) date.toLocalTime()
java.time.LocalDateTime java.sql.Timestamp Timestamp.valueOf(localDateTime) timestamp.toLocalDateTime()
java.time.ZoneId java.util.TimeZone Timezone.getTimeZone(id) timeZone.toZoneId()
java.time.format.DateTimeFormatter java.text.DateFormat formatter.toFormat()

原文地址:https://xudc.tech/2019/05/30/java8-date-time-api/

发布了60 篇原创文章 · 获赞 176 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/E09620126/article/details/90708018