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

本文介绍了Java8引入的新时间日期API,包括LocalDate、LocalTime、LocalDateTime的使用,Instant时间戳,Duration和Period的日期间隔计算,TemporalAdjuster时间操纵,DateTimeFormatter的解析与格式化,以及ZoneId的时区处理。此外,还讨论了新API如何与传统日期处理进行转换。
摘要由CSDN通过智能技术生成

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.DateDate.from(instant)date.toInstant()
java.time.Instant java.sql.TimestampTimestamp.from(instant)timestamp.toInstant()
java.time.ZonedDateTime java.util.GregorianCalendarGregorianCalendar.from(zonedDateTim e)cal.toZonedDateTime()
java.time.LocalDate java.sql.TimeDate.valueOf(localDate)date.toLocalDate()
java.time.LocalTime java.sql.TimeDate.valueOf(localDate)date.toLocalTime()
java.time.LocalDateTime java.sql.TimestampTimestamp.valueOf(localDateTime)timestamp.toLocalDateTime()
java.time.ZoneId java.util.TimeZoneTimezone.getTimeZone(id)timeZone.toZoneId()
java.time.format.DateTimeFormatter java.text.DateFormatformatter.toFormat()

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值