Java8 time API

版权声明:本文注明出处可以转载。 https://blog.csdn.net/lzxomg/article/details/78160097
package com.lzx;

import java.time.*;
import java.time.chrono.ChronoLocalDateTime;
import java.time.chrono.Chronology;
import java.time.chrono.HijrahChronology;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoUnit;
import java.time.temporal.IsoFields;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;
import static java.time.temporal.ChronoUnit.DAYS;
import static java.time.temporal.ChronoUnit.YEARS;
import static java.time.temporal.TemporalAdjusters.*;

public class Java8DateTimeDemo {
    /**目前Java8新增了java.time包定义的类表示日期-时间概念的规则,很方便使用;最重要的一点是值不可变,且线程安全。
     * 历史悠久的 Date 类新增了 toInstant() 方法,用于把 Date 转换成新的表示形式。
     * 在java8中,java.time包下主要包含下面几个主要的类:
     * LocalDate:本地日期 只包含日期,比如:2016-10-20 它可以用来存储生日,周年纪念日,入职日期等。
     * LocalTime:本地时间 只包含时间,比如:23:12:10
     * LocalDateTime:本地日期时间 包含日期和时间,比如:2016-10-20 23:14:21,不过还是没有偏移信息或者说时区。
     * DateTimeFormatter:时间格式化
     * Clock:时钟,比如获取目前美国纽约的时间
     * Instant:时间戳 瞬时时间
     * Duration:持续时间,时间差
     * Period:时间段
     * ChronoUnit ----- 计算出两点之间的时间量,例如ChronoUnit.DAYS.between(t1, t2)
     * TemporalAdjusters
     * ZoneOffset:时区偏移量,比如:+8:00
     * ZonedDateTime:带时区的完整的日期时间,偏移量是以UTC/格林威治时间为基准的
     */
    public static void main(String[] args) {
        /*  //Create date
        LocalDate localDate = LocalDate.now();
      System.out.println("The local date is :: " + localDate);
        Period period = Period.between(localDate, localDate.plus(2, ChronoUnit.DAYS));
        System.out.println(period.getDays());*/
        /*Calendar calendar = Calendar.getInstance();
        calendar.set(2016, 5, 2);
         Date date = calendar.getTime();
        Instant instant = date.toInstant();
        System.out.println(instant);
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(df.format(date));*/


        //getDateTime(); //获取日期、时间、日期时间
        //parse_format();
        dateTimeOperation();
        //testDuration();

    }

    public static  void  getDateTime(){
        // 获取今天的日期,现在的时间
        LocalDate today = LocalDate.now();  // 今天的日期
        // 获取指定日期(月从1开始不用减1)
        //today = LocalDate.of(2018, 10, 01);
        //today = LocalDate.parse("2017-08-07");
        // 用LocalDate获取 年 月 日 月份的天数
        //System.out.printf("年 : %d 月 : %d 日 : %d 月份的天数: %d \t %n", todayDate.getYear(), todayDate.getMonthValue(), todayDate.getDayOfMonth(), localDate.lengthOfMonth()); //结果  年 : 2017 月 : 10 日 : 4
        // 获取当前的时间
        LocalTime nowTime = LocalTime.now();    //如果不想显示毫秒  LocalTime.now().withNano(0);
        // 指定时间
        //nowTime =LocalTime.of(14, 10, 21); //14:10:21
        //nowTime =LocalTime.parse("12:00:01"); // 12:00:01

        System.out.println("今天的日期:"+today+",现在的时间:"+nowTime); //结果 今天的日期:2017-10-04,现在的时间:13:33:34.190

        LocalDateTime dateTime = LocalDateTime.now();
        //dateTime = LocalDateTime.of(2018, 10, 01, 10, 01);
        //dateTime = LocalDateTime.parse("2018-10-01 10:01:00");
        System.out.println("日期时间:"+dateTime); //结果 日期时间:2017-10-04T13:36:43.131 //不想显示纳秒 dateTime.withNano(0)

    }

    /**
     *  日期时间格式解析、格式化
     *  在java8之前,我们进行时间格式化主要是使用SimpleDateFormat,而在java8中,主要是使用DateTimeFormatter,java8中,预定义了一些标准的时间格式,我们可以直接将时间转换为标准的时间格式
     */
    public static void parse_format(){

        // 使用预定义的格式器来对日期进行解析/格式化
        // 在Java 8之前,时间日期的格式化 SimpleDateFormat并不是线程安全的,而如果用作本地变量来格式化的话又显得有些笨重。
        // 多亏了线程本地变量,这使得它在多线程环境下也算有了用武之地,但Java维持这一状态也有很长一段时间了。这次它引入了一个全新的线程安全的日期与时间格式器。
        // 它还自带了一些预定义好的格式器,包含了常用的日期格式。

        /*// 从字符串解析一个LocalDate类型  //用不习惯这样的API
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(Locale.GERMAN);
        LocalDate localDate = LocalDate.parse("04.10.2018", dateFormatter);
        System.out.println("localDate="+localDate);*/
        try {
            LocalDate formatted = LocalDate.parse("20180116",DateTimeFormatter.BASIC_ISO_DATE);
            System.out.println(formatted); //输出 2018-01-16

            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            LocalDateTime parsed = LocalDateTime.parse("2018-10-01 10:01:00",formatter);  // 从字符串解析一个LocalDateTime类型  指定模式"yyyy-MM-dd HH:mm:ss"。
            System.out.println(parsed);
        } catch (DateTimeParseException ex) {
            ex.printStackTrace();
        }

        // 对日期进行格式化,转换成字符串
        try {
            LocalDateTime date = LocalDateTime.now();
            //当然,很多时间标准的时间格式可能也不满足我们的要求,我们需要转为自定义的时间格式
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            String strDate = date.format(formatter); //LocalDate对象.format()
            //String strDate = formatter.format(date); //格式化对象.format()
            System.out.println("LocalDate格式化字符串输出="+strDate);
        } catch (DateTimeException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * 各种日期运算、比较、判断
     */
    public static void dateTimeOperation(){
        // 日期时间的加减
        LocalDate today = LocalDate.now();
        LocalTime time = LocalTime.now();

        System.out.println(today.plus(2, DAYS)); //add 2 days to the today's date.
        System.out.println(today.minus(2, DAYS)); //substract 2 days from today

        // 增加时间里面的小时数
        System.out.println(time.plus(2, ChronoUnit.HOURS)); // 由于LocalDate也是不可变的,因此任何修改操作都会返回一个新的实例
        System.out.println(time.plusHours(2));

        // 获取1周后的日期
        LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS); // 由于LocalDate也是不可变的,因此任何修改操作都会返回一个新的实例
        System.out.println("Today is : " + today);
        System.out.println("Date after 1 week : " + nextWeek);
        //一年前后的日期
        System.out.println("一年前 : " + today.minus(1, YEARS));
        System.out.println("一年后 : " + today.plus(1, YEARS));

        System.out.println("------------------------------------------------");
        //今年的第一天
        System.out.println("今年的第一天:"+today.with(firstDayOfYear())); //2017-01-01
        //今年的最后一天
        System.out.println("今年的最后一天:"+today.with(lastDayOfYear())); //2017-12-31
        //明年的第一天
        System.out.println("明年的第一天:"+today.with(firstDayOfNextYear())); //2018-01-01

        //取当前月的第1天
        System.out.println("当前月的第1天:"+today.with(TemporalAdjusters.firstDayOfMonth()));
        //取当前月的第1天,另外一种写法
        System.out.println("当前月的第1天,另外一种写法:"+today.withDayOfMonth(1));

        //取当前月的最后1天,不用考虑大月,小月,平年,闰年
        System.out.println("当前月的最后1天:"+today.with(lastDayOfMonth()));

        //当前月第一个满足星期三的日期
        System.out.println("当前月第一个满足星期三的日期:"+today.with(firstInMonth(DayOfWeek.WEDNESDAY)));
        //当前月最后一个满足是星期四的日期
        System.out.println("当前月最后一个满足是星期四的日期:"+today.with(lastInMonth(DayOfWeek.THURSDAY)));

        //为本月第一个星期三
        LocalDate localDate1 = LocalDate.of(2017,10,05);
        LocalDate date12 = localDate1.with(previousOrSame(DayOfWeek.WEDNESDAY));
        System.out.println("当前月第一个星期三"+date12);

        //当前月的第二周的星期天
        System.out.println("当前月的第二周的星期天:"+today.with(dayOfWeekInMonth(2,DayOfWeek.SUNDAY)));

        //下个月的第一天
        System.out.println("下个月的第一天:"+today.with(firstDayOfNextMonth()));

        //下一周的星期天
        System.out.println("下一周的星期天:"+today.with(nextOrSame(DayOfWeek.SUNDAY)));

        //上个星期天的日期
        System.out.println("上个星期天的日期:"+today.with(previous(DayOfWeek.SUNDAY)));
        LocalDate date11 = today.with(previousOrSame(DayOfWeek.SUNDAY));
        System.out.println("上个星期天的日期:"+date11);
        //下个星期天的日期
        System.out.println("下个星期天的日期:"+today.with(next(DayOfWeek.SUNDAY)));

        //指定日期的下一周的星期天
        LocalDate localDate2 = LocalDate.of(2017,10,05);
        System.out.println("指定日期的下一周的星期天:"+localDate2.with(nextOrSame(DayOfWeek.SUNDAY)));

        System.out.println("------------------------------------------------");

        //检查两个日期是否相等 判断两个日期是不是同一天
        System.out.println("本月份天数:"+today.lengthOfMonth());

        //检查闰年 LocalDate类有一个isLeapYear()的方法能够返回当前LocalDate对应的那年是否是闰年。
        if(today.isLeapYear())
            System.out.println("今年是闰年");
        else
            System.out.println("今年是平年");

        LocalDate nationalDay = LocalDate.of(2017, 10, 1);
        if(nationalDay.equals(LocalDate.now()))
            System.out.printf("今天 %s , nationalDay %s 是同一天。 %n", today, nationalDay);
        else
            System.out.println("不是同一天。");
        // 日期前后比较
        // LocalDate类有一个isBefore()和isAfter()方法可以用来比较两个日期。如果调用方法的那个日期比给定的日期要早的话,isBefore()方法会返回true。
        LocalDate yesterday = today.minus(1, DAYS);
        if(yesterday.isBefore(today)){
            System.out.println("昨天在今天之前。");
        }
        LocalDate tomorrow = LocalDate.of(2017, 10, 05);
        if(tomorrow.isAfter(today)){
            System.out.println("明天在今天后面。");
        }

        //检查重复事件,比如说生日或者账单日检查
        //在java8中,可以使用MonthDay,该类不包含年份信息,当然还有一个类是YearMonth
        LocalDate dateOfBirth = LocalDate.of(1938, 10, 01);
        MonthDay monthDayOfBirth = MonthDay.of(dateOfBirth.getMonth(), dateOfBirth.getDayOfMonth()); //月日对象 从LoalDate对象取值
        MonthDay currentMonthDay = MonthDay.from(today); ///月日对象 来自 今天的日期
        if(currentMonthDay.equals(monthDayOfBirth)){
            System.out.println("生日快乐!! 没有准备礼物,但是我有最真诚的祝福。\"#$%^&*($%^&&*(*&*\"");
        }else{
            System.out.println("Sorry, today is not your birthday");
        }
        // 信用卡过期时间 定期存款到期日 ,证件到期 YearMonth
        // 你可以用这个类来找出那个月有多少天,lengthOfMonth()这个方法返回的是这个YearMonth实例有多少天,这对于检查2月到底是28天还是29天可是非常有用的。
        YearMonth currentYearMonth = YearMonth.now();
        System.out.printf("年月: %s %n", currentYearMonth);
        YearMonth creditCardExpiry = YearMonth.of(2018, Month.FEBRUARY);
        System.out.printf("有效期限: %s,有效期限月份天数: %d %n", creditCardExpiry, creditCardExpiry.lengthOfMonth());

        //两个日期之前时间差 年 月 周 日
        //Period类比较天数返回的值,并不是2个日期之间总共的天数差,而是一个相对天数差,比如,10月4日,和12月16日,他比较的是仅仅2个天之间的差,那1号和2号,相差12天
        //所以我们可以使用until,并指明精度单位是days,就可以计算真正的天数差了。
        LocalDate localDate = LocalDate.of(2018, Month.DECEMBER, 16);
        Period p = Period.between(today, localDate);
        System.out.println("时间相隔: " +p.getYears()+"年"+ p.getMonths()+"月"+p.getDays()+"天" );
        System.out.println("相隔天数: " +today.until(localDate, DAYS)+"天" );

        //两个日期之前时间差 纳秒
       /* Duration d1 = Duration.between( new Date(1507101039511L).toInstant(),Instant.now());
        System.out.println("秒差: "+d1.getSeconds());*/
        //Duration类,它持有的时间精确到秒和纳秒。这使得我们可以很容易得计算两个日期之间的不同.
        final LocalDateTime from = LocalDateTime.of( 2014, Month.APRIL, 16, 0, 0, 0 );
        final LocalDateTime to = LocalDateTime.of( 2015, Month.APRIL, 16, 23, 59, 59 );
        final Duration duration = Duration.between( from, to );
        System.out.println( "Duration in days: " + duration.toDays() );
        System.out.println( "Duration in hours: " + duration.toHours() );


    }

    public static void testDuration() {
        // 表示两个瞬时时间的时间段
        Duration d1 = Duration.between(Instant.ofEpochMilli(System.currentTimeMillis() - 12323123), Instant.now());
        // 得到相应的时差

        System.out.println(d1.toDays());
        System.out.println(d1.toHours());
        System.out.println(d1.toMinutes());
        System.out.println(d1.toMillis());
        System.out.println(d1.toNanos());
        // 1天时差 类似的还有如ofHours()
        Duration d2 = Duration.ofDays(1);
        System.out.println(d2.toDays());
    }

    public static void testClock() throws InterruptedException {
        //Java 8中自带了一个Clock类,你可以用它来获取某个时区下当前的瞬时时间,日期或者时间。
        //Clock类提供了访问当前日期和时间的方法。Clock使用时区来访问当前的instant, date和time。
        //Clock类可以替换 System.currentTimeMillis() 和 TimeZone.getDefault()。

        // 时钟提供给我们用于访问某个特定 时区的 瞬时时间、日期 和 时间的。
        Clock c1 = Clock.systemUTC(); // 系统默认UTC时钟(当前瞬时时间
        System.out.println( "时间日期:"+c1.instant() );
        System.out.println( "时间毫秒值:"+c1.millis() ); // 每次调用将返回当前瞬时时间(UTC)

        //相当于System.currentTimeMillis())
        Clock c2 = Clock.systemDefaultZone(); // 系统默认时区时钟(当前瞬时时间)
        System.out.println( "系统时间日期:"+c2.instant() );
        System.out.println( "时间毫秒:"+c2.millis() );

        Clock c31 = Clock.system(ZoneId.of("Europe/Paris")); // 巴黎时区
        System.out.println(c31.instant()); // 每次调用将返回当前瞬时时间(UTC)
        Clock c32 = Clock.system(ZoneId.of("Asia/Shanghai"));// 上海时区
        System.out.println(c32.instant());// 每次调用将返回当前瞬时时间(UTC)

        Clock c4 = Clock.fixed(Instant.now(), ZoneId.of("Asia/Shanghai"));// 固定上海时区时钟
        System.out.println(c4.millis());
        Thread.sleep(1000);
        System.out.println(c4.millis()); // 不变 即时钟时钟在那一个点不动

        Clock c5 = Clock.offset(c1, Duration.ofSeconds(2)); // 相对于系统默认时钟两秒的时钟
        System.out.println(c1.millis());
        System.out.println(c5.millis());
    }

    public static void testInstant() {
        // 当前时间戳 瞬时时间 相当于以前的System.currentTimeMillis()
        // 可以看出,当前时间戳是包含日期与时间的,与java.util.Date很类似,事实上Instant就是Java 8前的Date,你可以使用这两个类中的方法来在这两个类型之间进行转换,
        // 比如Date.from(Instant)是用来将Instant转换成java.util.Date的,而Date.toInstant()是将Date转换成Instant的。

        Clock clock1 = Clock.systemUTC();
        //某一个特定的时间点也可以使用Instant类来表示,Instant类也可以用来创建老的java.util.Date对象。
        Instant instant = clock1.instant();
        Date javadate = Date.from(instant);
        System.out.println( "date:"+javadate);


        Instant instant1 = Instant.now();
        System.out.println(instant1.getEpochSecond());// 精确到秒 得到相对于1970-01-01 00:00:00 UTC的一个时间
        System.out.println(instant1.toEpochMilli()); // 精确到毫秒
        Instant instant2 = Instant.now(clock1);// 得到时钟的瞬时时间
        System.out.println(instant2.toEpochMilli());
        Clock clock2 = Clock.fixed(instant1, ZoneId.systemDefault()); // 固定瞬时时间时钟
        Instant instant3 = Instant.now(clock2);// 得到时钟的瞬时时间
        System.out.println(instant3.toEpochMilli());// equals instant1

    }

    public static void testLocalDateTime() {
        // 使用默认时区时钟瞬时时间创建 Clock.systemDefaultZone() -->即相对于  ZoneId.systemDefault()默认时区
        LocalDateTime now = LocalDateTime.now();
        System.out.println(now);
        // 自定义时区
        LocalDateTime now2 = LocalDateTime.now(ZoneId.of("Europe/Paris"));
        System.out.println(now2);// 会以相应的时区显示日期
        // 自定义时钟
        Clock clock = Clock.system(ZoneId.of("Asia/Dhaka"));
        LocalDateTime now3 = LocalDateTime.now(clock);
        System.out.println(now3);// 会以相应的时区显示日期
        // 不需要写什么相对时间 如java.util.Date 年是相对于1900 月是从0开始
        // 2013-12-31 23:59
        LocalDateTime d1 = LocalDateTime.of(2013, 12, 31, 23, 59);
        // 年月日 时分秒 纳秒
        LocalDateTime d2 = LocalDateTime.of(2013, 12, 31, 23, 59, 59, 11);
        // 使用瞬时时间 + 时区
        Instant instant = Instant.now();
        LocalDateTime d3 = LocalDateTime.ofInstant(Instant.now(), ZoneId.systemDefault());
        System.out.println(d3);
        // 解析String--->LocalDateTime
        LocalDateTime d4 = LocalDateTime.parse("2013-12-31T23:59");
        System.out.println(d4);
        LocalDateTime d5 = LocalDateTime.parse("2013-12-31T23:59:59.999");// 999毫秒
        // 等价于999000000纳秒
        System.out.println(d5);
        // 使用DateTimeFormatter API 解析 和 格式化
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
        LocalDateTime d6 = LocalDateTime.parse("2013/12/31 23:59:59", formatter);
        System.out.println(formatter.format(d6));
        // 时间获取
        System.out.println(d6.getYear());
        System.out.println(d6.getMonth());
        System.out.println(d6.getDayOfYear());
        System.out.println(d6.getDayOfMonth());
        System.out.println(d6.getDayOfWeek());
        System.out.println(d6.getHour());
        System.out.println(d6.getMinute());
        System.out.println(d6.getSecond());
        System.out.println(d6.getNano());
        // 时间增减
        LocalDateTime d7 = d6.minusDays(1);
        LocalDateTime d8 = d7.plus(1, IsoFields.QUARTER_YEARS);
        // LocalDate 即年月日 无时分秒
        // LocalTime即时分秒 无年月日
        // API和LocalDateTime类似就不演示了
    }

    public static void testZonedDateTime() {

        /*// 处理不同时区的时间
        // java8中,将日期,时间,时区都很好的进行了分离。

        //查看当前的时区
        ZoneId defaultZone = ZoneId.systemDefault();
        System.out.println(defaultZone); //Asia/Shanghai

        //查看美国纽约当前的时间
        ZoneId america = ZoneId.of("America/New_York");
        LocalDateTime shanghaiTime = LocalDateTime.now();
        LocalDateTime americaDateTime = LocalDateTime.now(america);
        System.out.println(shanghaiTime); //2016-11-06T15:20:27.996
        System.out.println(americaDateTime); //2016-11-06T02:20:27.996 ,可以看到美国与北京时间差了13小时

        //带有时区的时间
        ZonedDateTime americaZoneDateTime = ZonedDateTime.now(america);
        System.out.println(americaZoneDateTime); //2016-11-06T02:23:44.863-05:00[America/New_York]*/
        /*
        // 处理不同的时区 Java 8不仅将日期和时间进行了分离,同时还有时区。现在已经有好几组与时区相关的类了,比如ZonId代表的是某个特定的时区,而ZonedDateTime代表的是带时区的时间。它等同于Java 8以前的GregorianCalendar类。使用这个类,你可以将本地时间转换成另一个时区中的对应时间,比如下面这个例子:
        // Date and time with timezone in Java 8 ZoneId america = ZoneId.of("America/New_York");
        LocalDateTime localtDateAndTime = LocalDateTime.now();
        ZonedDateTime dateAndTimeInNewYork = ZonedDateTime.of(localtDateAndTime, america );
        System.out.println("Current date and time in a particular timezone : " + dateAndTimeInNewYork);



        // 带时区偏移量的日期与时间
        // 在Java 8里面,你可以用ZoneOffset类来代表某个时区,比如印度是GMT或者UTC5:30,你可以使用它的静态方法ZoneOffset.of()方法来获取对应的时区。只要获取到了这个偏移量,你就可以拿LocalDateTime和这个偏移量创建出一个OffsetDateTime。
        // 可以看到现在时间日期与时区是关联上了。还有一点就是,OffSetDateTime主要是给机器来理解的,如果是给人看的,可以使用ZoneDateTime类
        LocalDateTime datetime = LocalDateTime.of(2014, Month.JANUARY, 14, 19, 30);
        ZoneOffset offset = ZoneOffset.of("+05:30");
        OffsetDateTime date = OffsetDateTime.of(datetime, offset);
        System.out.println("Date and Time with timezone offset in Java : " + date);
*/


        // 即带有时区的date-time 存储纳秒、时区和时差(避免与本地date-time歧义)。
        // API和LocalDateTime类似,只是多了时差(如2013-12-20T10:35:50.711+08:00[Asia/Shanghai])
        ZonedDateTime now = ZonedDateTime.now();
        System.out.println(now);
        ZonedDateTime now2 = ZonedDateTime.now(ZoneId.of("Europe/Paris"));
        System.out.println(now2);
        // 其他的用法也是类似的 就不介绍了
        ZonedDateTime z1 = ZonedDateTime.parse("2013-12-31T23:59:59Z[Europe/Paris]");
        System.out.println(z1);
    }

    public static void testChronology() {
        // 提供对java.util.Calendar的替换,提供对年历系统的支持
        Chronology c = HijrahChronology.INSTANCE;
        ChronoLocalDateTime d = c.localDateTime(LocalDateTime.now());
        System.out.println(d);
    }

    /**
     * 新旧日期时间类与Date类的相互转化
     */
    public static void newOldDateConversion() {
        // 在转换中,我们需要注意,因为java8之前Date是包含日期和时间的,
        // 而LocalDate只包含日期,LocalTime只包含时间,所以与Date在互转中,势必会丢失日期或者时间,或者会使用起始时间。如果转LocalDateTime,那么就不存在信息误差。

        //Date与Instant的相互转化
        Instant instant  = Instant.now();
        Date date = Date.from(instant);
        Instant instant2 = date.toInstant();

        //Date转为LocalDateTime
        Date date2 = new Date();
        LocalDateTime localDateTime2 = LocalDateTime.ofInstant(date2.toInstant(), ZoneId.systemDefault());

        //LocalDateTime转Date
        LocalDateTime localDateTime3 = LocalDateTime.now();
        Instant instant3 = localDateTime3.atZone(ZoneId.systemDefault()).toInstant();
        Date date3 = Date.from(instant);

        //LocalDate转Date
        //因为LocalDate不包含时间,所以转Date时,会默认转为当天的起始时间,00:00:00
        LocalDate localDate4 = LocalDate.now();
        Instant instant4 = localDate4.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();
        Date date4 = Date.from(instant);
    } 


	/**
     * Java 8中日期与时间API的几个关键点
     * 看完了这些例子后,我相信你已经对Java 8这套新的时间日期API有了一定的了解了。现在我们来回顾下关于这个新的API的一些关键的要素。
     * 它提供了javax.time.ZoneId用来处理时区。
     * 它提供了LocalDate与LocalTime类
     * Java 8中新的时间与日期API中的所有类都是不可变且线程安全的,这与之前的Date与Calendar API中的恰好相反,那里面像java.util.Date以及SimpleDateFormat这些关键的类都不是线程安全的。
     * 新的时间与日期API中很重要的一点是它定义清楚了基本的时间与日期的概念,比方说,瞬时时间,持续时间,日期,时间,时区以及时间段。它们都是基于ISO日历体系的。
     * 每个Java开发人员都应该至少了解这套新的API中的这五个类:
     * Instant 它代表的是时间戳,比如2014-01-14T02:20:13.592Z,这可以从java.time.Clock类中获取,像这样: Instant current = Clock.system(ZoneId.of(“Asia/Tokyo”)).instant();
     * LocalDate 它表示的是不带时间的日期,比如2014-01-14。它可以用来存储生日,周年纪念日,入职日期等。
     * LocalTime – 它表示的是不带日期的时间
     * LocalDateTime – 它包含了时间与日期,不过没有带时区的偏移量
     * ZonedDateTime – 这是一个带时区的完整时间,它根据UTC/格林威治时间来进行时区调整
     * 这个库的主包是java.time,里面包含了代表日期,时间,瞬时以及持续时间的类。它有两个子package,一个是java.time.foramt,这个是什么用途就很明显了,还有一个是java.time.temporal,它能从更低层面对各个字段进行访问。
     * 时区指的是地球上共享同一标准时间的地区。每个时区都有一个唯一标识符,同时还有一个地区/城市(Asia/Tokyo)的格式以及从格林威治时间开始的一个偏移时间。比如说,东京的偏移时间就是+09:00。
     * OffsetDateTime类实际上包含了LocalDateTime与ZoneOffset。它用来表示一个包含格林威治时间偏移量(+/-小时:分,比如+06:00或者 -08:00)的完整的日期(年月日)及时间(时分秒,纳秒)。
     * DateTimeFormatter类用于在Java中进行日期的格式化与解析。与SimpleDateFormat不同,它是不可变且线程安全的,如果需要的话,可以赋值给一个静态变量。DateTimeFormatter类提供了许多预定义的格式器,你也可以自定义自己想要的格式。当然了,根据约定,它还有一个parse()方法是用于将字符串转换成日期的,如果转换期间出现任何错误,它会抛出DateTimeParseException异常。类似的,DateFormatter类也有一个用于格式化日期的format()方法,它出错的话则会抛出DateTimeException异常。
     * 再说一句,“MMM d yyyy”与“MMm dd yyyy”这两个日期格式也略有不同,前者能识别出”Jan 2 2014″与”Jan 14 2014″这两个串,而后者如果传进来的是”Jan 2 2014″则会报错,因为它期望月份处传进来的是两个字符。为了解决这个问题,在天为个位数的情况下,你得在前面补0,比如”Jan 2 2014″应该改为”Jan 02 2014″。
     * 关于Java 8这个新的时间日期API就讲到这了。这几个简短的示例 对于理解这套新的API中的一些新增类已经足够了。由于它是基于实际任务来讲解的,因此后面再遇到Java中要对时间与日期进行处理的工作时,就不用再四处寻找了。我们学习了如何创建与修改日期实例。我们还了解了纯日期,日期加时间,日期加时区的区别,知道如何比较两个日期,如何找到某天到指定日期比如说下一个生日,周年纪念日或者保险日还有多少天。我们还学习了如何在Java 8中用线程安全的方式对日期进行解析及格式化,而无需再使用线程本地变量或者第三方库这种取巧的方式。新的API能胜任任何与时间日期相关的任务。
     */

猜你喜欢

转载自blog.csdn.net/lzxomg/article/details/78160097