JDK8新特性之日期处理(二)

1.JDK8新特性之日期处理

1.1.带着问题学习

1.jdk8日期和 java.util.Date有哪些不同?
2.jdk8解决了哪些复杂的日期问题和提供了哪些现成的方法?

1.2.基本介绍

JDK8推出了lambda表达式、streams流、日期这些新特性以及一系列小优化,在这里主要介绍日期。
Java处理日期、日历和时间的不足之处:将 java.util.Date 设定为可变类型,以及 SimpleDateFormat 的非线程安全使其应用非常受限。然后 jdk8 中替换了SimpleDateFormat,在上面增加新的特性。
全新API的众多好处之一就是,明确了日期时间概念,例如:瞬时(instant)、长短(duration)、日期、时间、时区和周期。
同时继承了Joda 库按人类语言和计算机各自解析的时间处理方式。不同于老版本,新API基于ISO标准日历系统,java.time包下的所有类都是不可变类型而且线程安全。
注意:不要总想着把jdk8的LocalDate转换成Date,直接使用LocalDate替换Date就行了,包括数据库对应的Date属性。

1.3.关键类

  • Instant:瞬时实例。
  • LocalDate:本地日期,不包含具体时间 例如:2014-01-14 可以用来记录生日、纪念日、加盟日等。
  • LocalTime:本地时间,不包含日期,但是包含毫秒值,例如:获取当前时间 含有毫秒值 17:18:41.571,去掉毫秒值可以用LocalTime.now().withNano(0)。
  • LocalDateTime:组合了日期和时间,但不包含时差和时区信息。
  • ZonedDateTime:最完整的日期时间,包含时区和相对UTC或格林威治的时差。
    新API还引入了 ZoneOffSet 和 ZoneId 类,使得解决时区问题更为简便。解析、格式化时间的DateTimeFormatter类也全部重新设计。

2.怎么使用

2.1.LocalDate

    /**
     * 处理日期 LocalDate
     */
    @Test
    public static void localDateTest() {
        // 获取当前日期   2020-06-16
        LocalDate today = LocalDate.now();
        System.out.println(today);

        // 构造日期   2020-06-16
        LocalDate today2 = LocalDate.of(2020, 6, 16);
        System.out.println(today2);

        // 构造日期   2020-06-16    字符串严格按照yyyy-MM-dd
        LocalDate today3 = LocalDate.parse("2020-06-16");
        System.out.println(today3);

        // 本月第一天  2020-06-01
        LocalDate firstDayOfMonth = today.with(TemporalAdjusters.firstDayOfMonth());
        System.out.println(firstDayOfMonth);

        // 本月第二天  2020-06-02   第n天
        LocalDate secondDayOfMonth = today.withDayOfMonth(2);
        System.out.println(secondDayOfMonth);

        // 本月最后一天 2020-06-30  方便解决任何年份的二月份多少天
        LocalDate lastDayOfMonth = today3.with(TemporalAdjusters.lastDayOfMonth());
        System.out.println(lastDayOfMonth);

        // 获取2020年12月的第一个周一   2020-12-07
        LocalDate firstDayOf201712 = LocalDate.parse("2020-12-01").with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY));
        System.out.println(firstDayOf201712);
    }
结果
2020-06-16
2020-06-16
2020-06-16
2020-06-01
2020-06-02
2020-06-30
2020-12-07

2.2.LocalTime

    /**
     * 处理时间  LocalTime
     */
    @Test
    public static void localTimeTest() {
        //获取当前时间  含有毫秒值  17:18:41.571
        LocalTime now = LocalTime.now();
        System.out.println(now);

        //获取当前时间   去掉毫秒值   17:45:41
        LocalTime now1 = LocalTime.now().withNano(0);
        System.out.println(now1);
        //00:46:46.651  提供了把时分秒都设为0的方法
        LocalTime now2 = LocalTime.now().withHour(0);
        System.out.println(now2);

        //构造时间  00:20:55
        LocalTime time1 = LocalTime.of(0, 20, 55);
        System.out.println(time1);
        //构造时间  05:43:22
        LocalTime time2 = LocalTime.parse("05:43:22");
        System.out.println(time2);

        //标准时间 2020-06-16T17:53:15.930
        LocalDateTime lt = LocalDateTime.now();
        System.out.println(lt);
    }
结果
12:41:49.366
12:41:49
00:41:49.366
00:20:55
05:43:22
2020-06-16T12:41:49.378

2.3.LocalDateTime

    /**
     * 处理时间  LocalDateTime
     */
    @Test
    public static void localDateTimeTest() {
        LocalDateTime time = LocalDateTime.now();
        // 字符串表示
        System.out.println(time.toString());
        // 获取时间(LocalTime)
        System.out.println(time.toLocalTime());
        // 获取日期(LocalDate)
        System.out.println(time.toLocalDate());
        // 获取当前时间月份的第几天
        System.out.println(time.getDayOfMonth());
        // 获取当前周的第几天
        System.out.println(time.getDayOfWeek());
        // 获取当前时间在该年属于第几天
        System.out.println(time.getDayOfYear());
        System.out.println(time.getHour());
        System.out.println(time.getMinute());
        System.out.println(time.getMonthValue());
        System.out.println(time.getMonth());
        System.out.println("-----------------------------------");
        // 格式化输出
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("YYYY/MM/dd HH:mm:ss");
        System.out.println(time.format(formatter));
        // 格式化输出
        DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        System.out.println(time.format(formatter2));

        // 格式化输出
        DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern("HH:mm");
        System.out.println(time.format(formatter3));

        // 构造时间
        LocalDateTime startTime = LocalDateTime.of(2018, 1, 1, 20, 31, 20);
        LocalDateTime endTime = LocalDateTime.of(2018, 1, 3, 20, 31, 20);
        // 比较时间
        System.out.println(time.isAfter(startTime));
        System.out.println(time.isBefore(endTime));

        // 时间运算,相加相减
        System.out.println(time.plusYears(2)); // 加2年
        System.out.println(time.plusDays(2)); // 加两天
        System.out.println(time.minusYears(2)); // 减两年
        System.out.println(time.minusDays(2)); // 减两天

        // 获取毫秒数(使用Instant)
        System.out.println(time.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
        // 获取秒数(使用Instant)
        System.out.println(time.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond());
    }
结果
2020-06-16T12:43:03.232
12:43:03.232
2020-06-16
16
TUESDAY
168
12
43
6
JUNE
-----------------------------------
2020/06/16 12:43:03
2020-06-16 12:43:03
12:43
true
false
2022-06-16T12:43:03.232
2020-06-18T12:43:03.232
2018-06-16T12:43:03.232
2020-06-14T12:43:03.232
1592282583232
1592282583

2.4.LocalDate和Date互转

import org.junit.Test;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.Calendar;
import java.util.Date;

/**
 * Jdk8 日期辅助类
 * @author zhiqiang.feng
 * @date-time 2020/1/16 17:04
 **/
public class DateUtil {

    /**
     * 将LocalDateTime转为自定义的时间格式的字符串
     *
     * @param localDateTime
     * @param format
     * @return
     */
    public static String getDateTimeAsString(LocalDateTime localDateTime, String format) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format);
        return localDateTime.format(formatter);
    }

    /**
     * 将long类型的timestamp转为LocalDateTime
     *
     * @param timestamp
     * @return
     */
    public static LocalDateTime getDateTimeOfTimestamp(long timestamp) {
        Instant instant = Instant.ofEpochMilli(timestamp);
        ZoneId zone = ZoneId.systemDefault();
        return LocalDateTime.ofInstant(instant, zone);
    }

    /**
     * 将LocalDateTime转为long类型的timestamp
     *
     * @param localDateTime
     * @return
     */
    public static long getTimestampOfDateTime(LocalDateTime localDateTime) {
        ZoneId zone = ZoneId.systemDefault();
        Instant instant = localDateTime.atZone(zone).toInstant();
        return instant.toEpochMilli();
    }

    /**
     * 将某时间字符串转为自定义时间格式的LocalDateTime
     *
     * @param time
     * @param format
     * @return
     */
    public static LocalDateTime parseStringToDateTime(String time, String format) {
        DateTimeFormatter df = DateTimeFormatter.ofPattern(format);
        return LocalDateTime.parse(time, df);
    }


    /**
     * Date -> LocalDate
     *
     * @param date
     * @return
     */
    public static LocalDate transDateToLocalDate(Date date) {
        // atZone()方法返回在指定时区从此Instant生成的ZonedDateTime。
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
    }

    /**
     * LocalDate->Date
     *
     * @param localDate
     * @return
     */
    public static Date transLocalDateToDate(LocalDate localDate) {
        return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
    }

    /**
     * Date -> LocalDateTime
     *
     * @param date
     * @return
     */
    public static LocalDateTime transDateToLocalDateTime(Date date) {
        return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
    }

    /**
     * LocalDateTime -> Date
     *
     * @param localDateTime
     * @return
     */
    private static Date transLocalDateTimeToDate(LocalDateTime localDateTime) {
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * Date -> LocalTime
     *
     * @param date
     * @return
     */
    public static LocalTime transDateToLocalTime(Date date) {
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalTime();
    }

    /**
     * LocalTime -> Date
     *
     * @param localTime
     * @return
     */
    private static Date transLocalTimeToDate(LocalTime localTime) {
        return Date.from(LocalDateTime.of(LocalDate.now(), localTime)
                .atZone(ZoneId.systemDefault()).toInstant());
    }
}

3.总结

1.jdk8的DateTimeFormatter是线程安全的,而SimpleDateFormat不是线程安全的。
2.LocalDate:本地日期,不包含具体时间 例如:2014-01-14 可以用来记录生日、纪念日、加盟日等。
3.LocalTime:本地时间,不包含日期,但是包含毫秒值,例如:获取当前时间 含有毫秒值 17:18:41.571,去掉毫秒值可以用LocalTime.now().withNano(0)。
4.LocalDateTime:组合了日期和时间,但不包含时差和时区信息。
5.ZonedDateTime:最完整的日期时间,包含时区和相对UTC或格林威治的时差。

4.参考

Java8新特性之日期处理(也总结的很好):

https://segmentfault.com/a/1190000012922933

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值