• JDK 1.8 新特性之Date-Time API


    原文:点击查看

    1.8之前的日期类:

    1. 线程不安全:java.util.Date 这个类线程不安全,而且所有日期类都是可变的。
    2. 时间处理麻烦:默认的开始日期从1900年,不支持国际化,不提供时区支持,所以经常算出来的时间不是中国时间。
    3. 设计不好:java初学者接触到导包的时候,总会导错包,比如java.util和java.sql包中都有日期类,类名却是一样的。

    日期和时间

    Instant 本质上是一个数字时间戳。可以从a中检索当前的Instant Clock。这对于某个时间点的日志记录和持久性非常有用。
    LocalDate 没有时间存储日期。存储类似“2010-12-03”的日期,可用于存储生日。
    LocalTime 没有日期存储时间。存储像'11:30'这样的时间,可用于存储开盘或收盘时间。
    LocalDateTime 存储日期和时间。这会存储类似'2010-07-23T15:47:25.890'的日期时间。
    ZonedDateTime 使用时区存储日期和时间。如果您想要考虑到日期和时间的准确计算ZoneId,例如“欧洲/巴黎”,这将非常有用。在可能的情况下,建议使用没有时区的更简单的类。时区的广泛使用往往会给应用程序增加相当大的复杂性

    其他类型

    Month 用来存储一个月。这样可以隔离单个月份,例如“DECEMBER”。
    DayOfWeek 用来存储一个星期的日子。这样可以隔离存储一个星期几,例如“星期二”。
    Year 用来存储一年。这样可以隔离一年,例如'2010'。
    YearMonth 用来存储年加月份的时间。这会存储一年和一个月,例如“2010-12”,并可用于信用卡到期。
    MonthDay 用来存储月份和日子。它存储月份和日期,例如“12-03”,可用于存储年度活动,如生日,而不存储年份。

    在连接数据库的时候,使用 Java 8 新特性 TimeDateAPI,字段对应不上,或者存入的不是时间,或者直接抛异常,请更新对应数据库的 pom 依赖,添加以下支持

    Spring Data API 

    <!--java 8 time date 支持-->
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-java8</artifactId>
        <version>5.0.12.Final</version>
    </dependency>

    MyBatis

    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-typehandlers-jsr310</artifactId>
        <version>1.0.1</version>
    </dependency>

    Instant

    这个类是不可变的,线程安全。

    public class InstantDemo {
     
      public static void main(String[] args) {
        //===============================================================================
        // 1、获取当前时间戳
        //===============================================================================
        System.out.println(Instant.now());  // 2018-07-23T07:57:00.821Z
     
        //===============================================================================
        // 2、传入CharSequence类型,转换为instant对象
        //===============================================================================
        CharSequence text = "2010-10-31T07:57:00.821Z";
        Instant instant = Instant.parse(text);
        System.out.println(instant);  // 2010-10-31T07:57:00.821Z
        // 注意:格式不正确或者不存在该日期时,会抛出DateTimeParseException异常
     
        //===============================================================================
        // 3、比较时间(大于小于排序)
        //===============================================================================
        System.out.println(instant.isAfter(Instant.parse("2010-11-30T07:57:00.821Z")));
        // false 返回布尔值
        System.out.println(instant.isBefore(Instant.parse("2010-11-30T07:57:00.821Z")));
        // true 返回布尔值
        System.out.println(instant.compareTo(Instant.parse("2010-11-30T07:57:00.821Z")));
        // -1  compareTo 返回值int类型  等于返回 0 小于返回 -1 大于返回 1
        System.out.println(instant.equals(Instant.parse("2010-10-31T07:57:00.821Z")));
        // true  返回布尔值 比较两个时间是否相等
     
        //===============================================================================
        // 4、获取从1970-01-01T00:00:00Z到现在的秒数
        //===============================================================================
        System.out.println(instant.getEpochSecond());  // 1288511820  
        // 返回值long,注意返回的是秒!不是毫秒!
     
        //===============================================================================
        // 5、设置时区偏移
        //===============================================================================
        OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.ofHours(8));
        System.out.println(offsetDateTime); // 2010-10-31T15:57:00.821+08:00  
        // 返回值类型OffsetDateTime  我们在东八区,所以加上八小时,就是本地时间戳
     
      }
    }

    LocalDate

    LocalDate是一个不可变的类,它表示默认格式(yyyy-MM-dd)的日期,线程安全。

    public class LocalDateDemo {
     
      public static void main(String[] args) {
        //===============================================================================
        // 1、获取当前日期
        //===============================================================================
        LocalDate localDate = LocalDate.now();
        System.out.println(localDate); // 2018-07-23
        
        //===============================================================================
        // 2、构造LocalDate
        //===============================================================================
        CharSequence text = "2010-10-10";
        System.out.println(LocalDate.parse(text)); // 2010-10-10
        CharSequence date = "20101010";
        System.out.println(LocalDate.parse(date,DateTimeFormatter.BASIC_ISO_DATE));// 2010-10-10
        // 自定义对应格式的转换,JDK1.8给出了预定义的格式化 DateTimeFormatter.BASIC_ISO_DATE 就是其中之一
        CharSequence myDate = "2010年10月10日";
        System.out.println(LocalDate.parse(myDate,DateTimeFormatter.ofPattern("yyyy年MM月dd日"))); // 2010-10-10
        // 预定义格式没有的情况,也可以自定义
        System.out.println(LocalDate.of(2010, 10, 10));// 2010-10-10
        // 给出int类型对应的 年月日,亦可构造出LocalDate对象
        System.out.println(LocalDate.of(2010, Month.JULY, 10));// 2010-07-10
        // 月份亦可给出对应 Mouth 枚举
        System.out.println(LocalDate.ofEpochDay(123)); // 1970-05-04
        // 给出日子,计算出 从 1970-01-01 对应日子后的日期
        System.out.println(LocalDate.ofYearDay(2010, 163)); //2010-06-12
        // 传入 年,日数,计算出 对应该年份 对应日子后的日期
        
        //===============================================================================
        // 3、获取,年,月,日
        //===============================================================================
        System.out.println(localDate.getMonth()); // JULY  返回英文月份,对应 Mouth 枚举
        System.out.println(localDate.getMonthValue()); // 7  返回数字月份
        System.out.println(localDate.getYear()); // 2018  返回对应年
        System.out.println(localDate.getDayOfMonth()); // 23  返回对应月份中的日子
        System.out.println(localDate.getDayOfWeek()); // MONDAY  返回对应星期,对应 DayOfWeek 枚举
        System.out.println(localDate.getDayOfYear()); // 204 返回对应年份中的日子
        System.out.println(localDate.lengthOfMonth()); // 31 对应该月份有多少天
        System.out.println(LocalDate.parse("2004-02-10").lengthOfMonth());
        // 29 证明可以自动判断是否为闰年!!!
        System.out.println(localDate.lengthOfYear()); // 365 对应年份有多少天
        System.out.println(LocalDate.parse("2004-02-10").lengthOfYear());
        // 366 证明可以自动判断是否为闰年!!!
     
        //===============================================================================
        // 4、判断大于小于,排序,判断是否闰年
        //===============================================================================
        System.out.println(localDate.compareTo(LocalDate.parse("2000-01-01"))); // 18
        // 这里的 compareTo 方法为什么返回 18 请看下面详解!!!
        System.out.println(localDate.isAfter(LocalDate.parse("2000-01-01"))); // true
        System.out.println(localDate.isBefore(LocalDate.parse("2000-01-01"))); // false
        System.out.println(localDate.isEqual(LocalDate.parse("2000-01-01"))); // false
        System.out.println(localDate.isLeapYear());// false  返回布尔值,该年是否为闰年
        
        //===============================================================================
        // 5、日期的加减
        //===============================================================================
        System.out.println(localDate.plusMonths(1)); // 2018-08-23  加一个月
        System.out.println(localDate.plusMonths(-1)); // 2018-06-23 减去一个月,传入负数即可,下面的也是
        System.out.println(localDate.plusDays(1)); // 2018-07-24 加上一天
        System.out.println(localDate.plusMonths(1)); // 2018-08-23 加上一个月
        System.out.println(localDate.plusWeeks(1)); // 2018-07-30 加上一个星期
     
        //===============================================================================
        // 6、其他计算
        //===============================================================================
        System.out.println(localDate.withDayOfYear(123)); // 2018-05-03 计算当前年第123天的日期
     
      }
    }

    LocalTime

    LocalTime是一个不可变的日期时间对象,代表一个时间,通常被看作是小时 - 秒,这个类不可变,线程安全。

    public class LocalTimeDemo {
     
      public static void main(String[] args) {
        //===============================================================================
        // 1、获取当前时间
        //===============================================================================
        LocalTime time1 = LocalTime.now();
        System.out.println(time1); // 09:39:47.275
     
        //===============================================================================
        // 2、构造LocalTime
        //===============================================================================
        // 根据传入文本构造LocalTIme时间对象,格式不正确会抛出 java.time.format.DateTimeParseException 异常
        CharSequence text1 = "22:22:22";
        LocalTime localTime1 = LocalTime.parse(text1);
        System.out.println(localTime1); // 22:22:22
        // 传入自定义文本,自定义格式化 构造 LocalTime 对象
        CharSequence text2 = "11-11-11";
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("HH-mm-ss");
        LocalTime localTime2 = LocalTime.parse(text2, dateTimeFormatter);
        System.out.println(localTime2); // 11:11:11
        // 根据入参 时,分,秒,纳秒构造出LocalTime对象,24小时制
        // 如果入参不符合时间要求,例如传入25小时,61分钟,会抛出 java.time.DateTimeException 异常
        LocalTime time2 = LocalTime.of(13, 22);
        System.out.println(time2); // 13:22
        LocalTime time3 = LocalTime.of(14, 22, 31);
        System.out.println(time3); // 14:22:31
        LocalTime time4 = LocalTime.of(22, 43, 33, 422);
        System.out.println(time4); // 22:43:33.000000422
        // 根据分钟 构造 LocalTime 时间对象 超过最大分钟,会抛出 java.time.DateTimeException 异常
        LocalTime time5 = LocalTime.ofSecondOfDay(22324);
        System.out.println(time5); // 06:12:04
        // 根据纳秒构造LocalTime对象
        LocalTime time6 = LocalTime.ofNanoOfDay(1231);
        System.out.println(time6); // 00:00:00.000001231
     
        //===============================================================================
        // 3、获时,分,秒等
        //===============================================================================
        int hour = time1.getHour();
        int minute = time1.getMinute();
        int second = time1.getSecond();
        System.out.println("小时:" + hour + ",分钟:"
            + minute + ",秒数:" + second); // 小时:10,分钟:5,秒数:53
     
        //===============================================================================
        // 4、判断大于小于,排序,相差多少
        //===============================================================================
        // 判断时间1是否在时间2后
        boolean after = time1.isAfter(time2);
        System.out.println(after); // false
        // 判断时间1是否在时间2前
        boolean before = time1.isBefore(time2);
        System.out.println(before); // true
        // 排序比较,前者大于后者返回 1,否则 -1,相等 0
        int i = time1.compareTo(time2);
        System.out.println(i); // -1
        // 时间1和时间2相差多少小时,分钟,秒,大于为正数,小于为负数(坏处就是分跟分加减,秒跟秒加减)
        long betweenHours = ChronoUnit.HOURS.between(time1, time2);
        long betweenSeconds = ChronoUnit.SECONDS.between(time1, time2);
        long betweenMinutes = ChronoUnit.MINUTES.between(time1, time2);
        System.out.println("相差小时:" + betweenHours + " 分钟: " +
            betweenMinutes + " 秒数:" + betweenSeconds); // 相差小时:2 分钟: 178 秒数:10707
     
        //===============================================================================
        // 5、时间的加减,修改
        //===============================================================================
        // 加两小时,减去传入负数即可
        LocalTime time7 = time3.plusHours(2);
        System.out.println(time7); // 16:22:31
        // 减去10分钟
        LocalTime time8 = time3.plusMinutes(-10);
        System.out.println(time8); // 14:12:31
        // 加上30秒
        LocalTime time9 = time3.plusSeconds(30);
        System.out.println(time9); // 14:23:01
        // 修改小时
        LocalTime time10 = time3.withHour(23);
        System.out.println(time10); // 23:22:31
        // 修改分钟
        LocalTime time11 = time3.withMinute(11);
        System.out.println(time11); // 14:11:31
        // 修改秒数
        LocalTime time12 = time3.withSecond(50);
        System.out.println(time12); // 14:22:50
     
     
      //===============================================================================
        // 6、两个时间之间的相差秒数,小时
        
     //===============================================================================
        Duration duration = Duration.between(time3, time12);
        long days = duration.toDays();
        long hours = duration.toHours();
        long millis = duration.toMillis()/1000;
     
      }
    }

    LocalDateTime

    是一个不可变的日期时间对象,代表日期时间,年-月-日-时-分-秒,线程安全

    public class LocalDateTimeDemo {
     
      public static void main(String[] args) {
        //===============================================================================
        // 1、获取当前日期时间
        //===============================================================================
        LocalDateTime localDateTime = LocalDateTime.now();
        System.out.println(localDateTime); // 2018-07-26T14:47:44.144
     
        //===============================================================================
        // 2、构造日期时间
        //===============================================================================
        CharSequence text = "2007-12-03T10:15:30";
        // 从一个文本字符串 获得 LocalDateTime实例
        LocalDateTime dateTime1 = LocalDateTime.parse(text);
        System.out.println(dateTime1); // 2007-12-03T10:15:30
     
        //===============================================================================
        // 3、获取,年,月,日,时等等
        //===============================================================================
        int dayOfMonth = localDateTime.getDayOfMonth();
        DayOfWeek dayOfWeek = localDateTime.getDayOfWeek();
        int dayOfYear = localDateTime.getDayOfYear();
        int hour = localDateTime.getHour();
        Month month = localDateTime.getMonth();
        int year = localDateTime.getYear();
        System.out.println(year + "" + month.toString() + "" + dayOfMonth + "" +
            hour + "" + "|||" + dayOfWeek + "|||" + dayOfYear);
        // 2018年JULY月31日9时|||TUESDAY|||212
      }
    }

    YearMonth

    是一个不变的日期时间对象,表示一年和一个月的组合。 可以获得可以从年和月派生的任何字段,例如四分之一年份。类线程安全

    public class YearMonthDemo {
     
      public static void main(String[] args) {
        //===============================================================================
        // 1、获取当前年月
        //===============================================================================
        YearMonth yearMonth = YearMonth.now();
        System.out.println(yearMonth); // 2018-07
     
        //===============================================================================
        // 2、构造年月
        //===============================================================================
        CharSequence text = "2018-01";
        YearMonth yearMonth1 = YearMonth.parse(text);
        System.out.println(yearMonth1); // 2018-01
        CharSequence text2 = "2018年02月";
        YearMonth yearMonth2 = YearMonth.parse(text2, DateTimeFormatter.ofPattern("yyyy年MM月"));
        System.out.println(yearMonth2); // 2018-02
     
        //===============================================================================
        // 3、获取,年,月
        //===============================================================================
        int year = yearMonth.getYear();
        Month month = yearMonth.getMonth();
        int monthValue = yearMonth.getMonthValue();
        System.out.println(year + "" + monthValue + "" + "mouth对象-》" + month);
        // 2018年7月mouth对象-》JULY
     
        //===============================================================================
        // 4、判断大于小于,排序,判断是否闰年
        //===============================================================================
        System.out.println(yearMonth.isAfter(yearMonth1));  // true
        System.out.println(yearMonth.isBefore(yearMonth1)); // false
        System.out.println(yearMonth.isLeapYear()); // 是否闰年 false
        System.out.println(yearMonth.compareTo(yearMonth1)); // 6 (这里为什么是6 上面有详解)
     
        //===============================================================================
        // 5、年月的加减,设置年月
        //===============================================================================
        YearMonth yearMonth3 = yearMonth.plusMonths(1);
        System.out.println(yearMonth3); // 2018-08
        YearMonth yearMonth4 = yearMonth.plusYears(-1);
        System.out.println(yearMonth4); // 2017-07
        YearMonth yearMonth5 = yearMonth.withMonth(5);
        System.out.println(yearMonth5); // 2018-05
        YearMonth yearMonth6 = yearMonth.withYear(2000);
        System.out.println(yearMonth6); // 2000-07
      }
    }

    MonthDay

    是一个不变的日期时间对象,代表一年和一个月的组合。 可以获得可以从月和日派生的任何字段,线程安全。

    public class MonthDayDemo {
     
      public static void main(String[] args) {
        //===============================================================================
        // 1、获取当前月日
        //===============================================================================
        MonthDay monthDay = MonthDay.now();
        System.out.println(monthDay); // --07-31
     
        //===============================================================================
        // 2、构造月日
        //===============================================================================
        CharSequence text1 = "--03-01";
        MonthDay monthDay1 = MonthDay.parse(text1);
        System.out.println(monthDay1); // --03-01
        CharSequence text2 = "11月23日";
        MonthDay monthDay2 = MonthDay.parse(text2, DateTimeFormatter.ofPattern("MM月dd日"));
        System.out.println(monthDay2); // --11-23
        MonthDay monthDay3 = MonthDay.of(2, 3);
        System.out.println(monthDay3); // --02-03
        MonthDay monthDay4 = MonthDay.of(Month.AUGUST, 22);
        System.out.println(monthDay4); // --08-22
     
        //===============================================================================
        // 3、获取 月,日
        //===============================================================================
        int monthValue = monthDay.getMonthValue();
        Month month = monthDay.getMonth();
        int dayOfMonth = monthDay.getDayOfMonth();
        System.out.println(monthValue + "" + dayOfMonth + "" + "月份-》" + month);
        // 7月31日月份-》JULY
     
        //===============================================================================
        // 4、判断大于小于,排序
        //===============================================================================
        System.out.println(monthDay.isAfter(monthDay1)); // true
        System.out.println(monthDay.isBefore(monthDay1)); // false
        System.out.println(monthDay.compareTo(monthDay1)); // 4 (这里为什么是4,上面有详解)
     
      }
    }

    常见需求

    public class NewTimeDemo {
     
      public static void main(String args[]) {
        // 输入 20180101
        CharSequence str = "20040201";
        // BASIC_ISO_DATE -》ISO日期格式化,格式或解析无偏移的日期,如“20111203”。
        LocalDate localDate = LocalDate.parse(str, BASIC_ISO_DATE);
     
        //===============================================================================
        // 1、 这个月月末
        //===============================================================================
        System.out.println("本月月末是:" + localDate.with(TemporalAdjusters.lastDayOfMonth()));
        // 本月月末是:2004-02-29
     
        //===============================================================================
        // 2、 下个月月初
        //===============================================================================
        System.out.println("下月月初是:" + localDate.with(TemporalAdjusters.firstDayOfNextMonth()));
        //下月月初是:2004-03-01
     
        //===============================================================================
        // 3、 下个月月末
        //===============================================================================
        System.out.println("下月月末是:" + localDate.with(TemporalAdjusters.firstDayOfNextMonth())
            .with(TemporalAdjusters.lastDayOfMonth()));
        // 下月月末是:2004-03-31
     
        //===============================================================================
        // 4、 给年月,计算当月天数
        //===============================================================================
        CharSequence str2 = "200102";
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMM");
        YearMonth ym = YearMonth.parse(str2, dateTimeFormatter);
        System.out.println(ym.lengthOfMonth()); // 28
     
        //===============================================================================
        // 5、 日期加减天数
        //===============================================================================
        System.out.println(localDate.plusDays(-1)); // 2004-01-31
     
        //===============================================================================
        // 6、 日期加减月份
        //===============================================================================
        System.out.println(localDate.plusMonths(-1)); // 2004-01-01
        System.out.println(localDate.plusMonths(1)); // 2004-03-01
     
        //===============================================================================
        //  7、 传参月份,日子,输出修改后的
        //===============================================================================
        try {
          System.out.println(localDate.withMonth(2).withDayOfMonth(2));
          // 2004-02-02
        } catch (DateTimeException exception) {
          System.out.println("输入日期异常!");
        }
        System.out.println(localDate.withDayOfMonth(1));
        // 2004-02-01
     
        //===============================================================================
        //  8、 小于15日,输出该月15日,否则输出下月1日
        //===============================================================================
        System.out.println("--------------------");
        if (localDate.getDayOfMonth() < 15) {
          System.out.println(localDate.withDayOfMonth(15));
        } else {
          System.out.println(localDate.with(TemporalAdjusters.firstDayOfNextMonth()));
        }
        // 2004-02-15
     
      }
    }
  • 相关阅读:
    RabbitMQ 记录
    RabbitMQ 问题记录
    (转)非常完善的Log4net详细说明
    (转)【推荐】初级.NET程序员,你必须知道的EF知识和经验
    移动相关
    (转)2014年最新前端开发面试题(题目列表+答案 完整版)
    Unity IOC容器的简单应用(转)
    httpclient模拟post请求json封装表单数据
    《SpringMVC从入门到放肆》六、SpringMVC开发Controller的方法总结
    《SpringMVC从入门到放肆》五、SpringMVC配置式开发(处理器适配器)
  • 原文地址:https://www.cnblogs.com/niudaben/p/12393897.html
Copyright © 2020-2023  润新知