Java 8 時間日期 API

Java 8 時間日期 API

Java 8 中新的時間與日期 API 中的全部類都是不可變且線程安全的,任何修改操做都會返回一個新的實例,而以前 java.util.Date、Calendar 以及 SimpleDateFormat 這些關鍵的類都不是線程安全的。java

java 8 對 時間api 從新進行了設計,經常使用的有如下幾種類。api

/***
          * LocalDate:表示不帶時間的日期
          * LocalTime:表示不帶日期的時間
          * LocalDateTime:日期和時間類
          * ZoneId:時區
          * ZonedDateTime:一個帶時區的完整時間
          * Instant:Unix 時間,它表明的是時間戳,好比 2018-01-14T02:20:13.592Z
          * Clock:獲取某個時區下當前的瞬時時間,日期或者時間
          * Duration:表示一個絕對的精確跨度,使用毫秒爲單位
          * Period:這個類表示與 Duration 相同的概念,可是以人們比較熟悉的單位表示,好比年、月、周
          * DateTimeFormatter:格式化輸出
          * TemporalAdjusters:得到指定日期時間等,如當月的第一天、今年的最後一天等
          * 
          */

方法安全

/**
          * of:靜態工廠方法,用於建立實例
          * now:靜態工廠方法,用當前時間建立實例
          * parse:靜態工廠方法,從字符串解析獲得對象實例
          * get:獲取時間日期對象的部分狀態。
          * is:檢查某些東西的是不是 true,例如比較時間先後
          * with:返回一個部分狀態改變了的時間日期對象拷貝
          * plus:返回一個時間增長了的、時間日期對象拷貝
          * minus:返回一個時間減小了的、時間日期對象拷貝
          * to:轉換到另外一個類型
          * at:把這個對象與另外一個對象組合起來,例如 date.atTime(time)
          * format:提供格式化時間日期對象的能力
          *
          */

LocalDate

/**
          *LocalDate
          */
         //LocalDate 是用來表示無時間的日期的,也不附帶任何與時區相關的信息
         LocalDate today = LocalDate.now();
         System.out.println("今日日期:"+ today);
         //它提供 plus()/minus() 方法能夠用來增長減小日、星期或者月,ChronoUnit 則用來表示這個時間單位。
         // 這些方法返回的是一個新的 LocalDate 實例的引用,由於 LocalTime 是不可變的,
         // 任何修改操做都會返回一個新的實例。
         LocalDate localDate = today.plusDays(1);

         //等價於  today.plus(1, ChronoUnit.DAYS);
         System.out.println("明日日期:"+ localDate);

         //日期減法
         LocalDate today1 = localDate.minus(1, ChronoUnit.DAYS);
         System.out.println("今日日期:" + today1);

LocalTime、LocalDateTime

LocalTime time = LocalTime.now();
         System.out.println("如今的時間:" + time);
         //小時
         int hour = time.getHour();
         System.out.println(hour);
         OffsetTime offsetTime = time.atOffset(ZoneOffset.UTC);
         System.out.println("UTC時間: "+offsetTime);


         /**
          *
          */
         //系統默認時間
         LocalTime time2 = LocalTime.now(Clock.systemDefaultZone());
         System.out.println("系統默認時間 : "+time2);


         LocalDate date =LocalDate.now();
         //LocalDateTime 將 LocalDate 和 LocalTime 結合起來
         LocalDateTime localDateTime = LocalDateTime.of(today,time2);
         System.out.println("LocalDateTime 將 LocalDate 和 LocalTime 結合起來 : " + localDateTime);

         //
         LocalDate localDate1 = LocalDate.of(2018, 11, 11);
         System.out.println("localDate1 自定義日期: " + localDate1);

         LocalTime localTime2 = LocalTime.of(12, 11, 11);
         LocalTime localTime3 = LocalTime.of(12, 12, 12, 12);
         System.out.println("LocalTime 自定義時間: " + localTime2);
         System.out.println("LocalTime 自定義時間帶納秒: " + localTime3);

DateTimeFormatter

格式化與解析時間對象 DateTimeFormatter
        格式器用於解析日期字符串和格式化日期輸出,
        建立格式器最簡單的方法是經過 DateTimeFormatter 的靜態工廠方法以及常量。
//1 自定義字母模式解析
         DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
         String format = localDate1.format(dateTimeFormatter);
         System.out.println(format);
         

         //2 經常使用 ISO 格式常量,如 ISO_LOCAL_DATE
          dateTimeFormatter = DateTimeFormatter.ISO_DATE;
          format = localDate1.format(dateTimeFormatter);
          System.out.println(format);

          //3 本地化樣式,如 ofLocalizedDate(FormatStyle.MEDIUM)
         dateTimeFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL);
         format = localDate1.format(dateTimeFormatter);
         System.out.println("FormatStyle.FULL = "+ format);//2018年11月11日 星期日

         dateTimeFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM);
         format = localDate1.format(dateTimeFormatter);
         System.out.println("FormatStyle.MEDIUM = " + format);//2018-11-11

         dateTimeFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG);
         format = localDate1.format(dateTimeFormatter);
         System.out.println("FormatStyle.LONG = "+ format);//2018-11-11


        //將日期格式化指定格式
         String format1 = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy,MM,dd"));
         System.out.println(format1);//2019,08,25

字符串格式化成日期app

LocalDate parse = LocalDate.parse("2019-10-10");
         System.out.println("默認: " + parse);
          //parse = LocalDate.parse("2019/8/10");//異常
         /**   默認的解析格式是 -
          *     public static final DateTimeFormatter ISO_LOCAL_DATE;
          *     static {
          *         ISO_LOCAL_DATE = new DateTimeFormatterBuilder()
          *                 .appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
          *                 .appendLiteral('-')
          *                 .appendValue(MONTH_OF_YEAR, 2)
          *                 .appendLiteral('-')
          *                 .appendValue(DAY_OF_MONTH, 2)
          *                 .toFormatter(ResolverStyle.STRICT, IsoChronology.INSTANCE);
          *     }
          */
         //System.out.println("默認: " + parse);

         //因此對於 "2019/8/10" 格式 咱們須要自定義 解析格式
         //注意 2019/08/10 不能寫成 2019/8/10 ,否則會拋出異常
         parse = LocalDate.parse("2019/08/10",DateTimeFormatter.ofPattern("yyyy/MM/dd"));
         System.out.println(parse); //2019-08-10

         //自定義解析格式
           dates = LocalDate.parse("20190825",
                 DateTimeFormatter.ofPattern("yyyyMMdd"));
         System.out.println(dates);//2019-08-25

         dates = LocalDate.parse("2019/08/25",
                 DateTimeFormatter.ofPattern("yyyy/MM/dd"));
         System.out.println(dates);//2019-08-25



     // 25/08/2019 - > 2019/08/25
         LocalDate parse2 = LocalDate.parse("25/08/2019",DateTimeFormatter.ofPattern("dd/MM/yyyy"));
         String format2 = parse2.format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
         System.out.println(format2);//2019/08/25



         LocalDate parse2 = LocalDate.parse("25/08/2019",DateTimeFormatter.ofPattern("dd/MM/yyyy"));
         System.out.println(parse2);//2019-08-25

Duration 與 Period

Duration 表示一個時間段,Duration 包含兩部分:seconds 表示秒,nanos 表示納秒,它們的組合表達了時間長度。
  
由於 Duration 表示時間段,因此 Duration 類中不包含 now() 靜態方法。注意,Duration 不包含毫秒這個屬性。
LocalDateTime from =LocalDateTime.of(2019,8,11,11,11,11,11);
         LocalDateTime to =LocalDateTime.of(2019,8,10,10,10,10,10);
         Duration between = Duration.between(from, to);
         long l = between.toDays();
         System.out.println("相差天數= " + l); // -1
         long l1 = between.toHours();
         System.out.println(l);// -1
         long l2 = between.toMinutes();
         System.out.println(l);// -1
         long l3 = between.toMillis();
         System.out.println(l);// -1
         long l4 = between.toNanos();
         System.out.println(l);// -1

Period 在概念上和 Duration 相似,區別在於 Period 是以年月日來衡量一個時間段。
Duration 用於計算兩個時間間隔,Period 用於計算兩個日期間隔,因此 between() 方法只能接收 LocalDate 類型的參數。ui

Period of1 = Period.of(2019, 10, 10);
         Period of2 = Period.of(2018, 9, 9);
         System.out.println(of1);//P2019Y10M10D

         LocalDate from1 =LocalDate.of(2019,8,11);
         LocalDate to2 =LocalDate.of(2018,8,10);
         Period between1 = Period.between(from1, to2);
         //Period 獲得的是差值的絕對值
         System.out.println("相差年 : " + between1.getYears());//-1
         System.out.println("相差月 : " + between1.getMonths());//0
         System.out.println("相差日 : " + between1.getDays());//-1


         //計算兩個時間的區間距離呢
         long year = from1.until(to2, ChronoUnit.YEARS);//-1
         long month = from1.until(to2, ChronoUnit.MONTHS);//-12
         long month1 = to2.until(from1, ChronoUnit.MONTHS);//12
         System.out.println(year);
         System.out.println(month);
         System.out.println("正值 " + month1);

Instant 與 Clock

//加1s
         Instant instant1 = Instant.ofEpochSecond(1);
         System.out.println(instant1);//1970-01-01T00:00:01Z

         //加10毫秒
         Instant instant2 = Instant.ofEpochMilli(10);
         System.out.println(instant2);//1970-01-01T00:00:00.010Z

         //當前時間 從1970-1-1號到如今的時間 至關於new Date()
         Instant instant = Instant.now();
         //秒  = 2019-08-24T14:49:36.344Z
         System.out.println(" 秒  = " + instant);

         //new Date()轉爲Instant
         Instant instant3 = new Date().toInstant();
         System.out.println(" 與new Date()轉換 " + instant3);//2019-08-24T14:57:07.464Z

         //解析時間
         Instant parse1 = Instant.parse("2019-08-24T14:59:16.708Z");
         System.out.println(parse1);
         //加10天
         Instant plus = parse1.plus(10, ChronoUnit.DAYS);
         //2019-09-03T14:59:16.708Z
         System.out.println(plus);
Clock 是時鐘系統,用於查找當前時刻。
      你能夠用它來獲取某個時區下當前的日期或者時間。能夠用 Clock 來替代舊的 System.currentTimeInMillis() 與 TimeZone.getDefault() 方法。
//世界協調時UTC
         Clock clock = Clock.systemUTC();
         System.out.println(clock.getZone());// time-zone  Z
         //獲取clock對應的毫秒數,與System.currentTimeMillis()輸出相同
         System.out.println(clock.millis());//



         //經過Clock獲取當前時刻
         System.out.println("經過Clock獲取當前時刻 " + clock.instant());//


         //默認時區時間
         Clock clock1 = Clock.systemDefaultZone();
         System.out.println(clock1.instant());

         //自定義時區
         Clock clock2 = clock1.withZone(ZoneId.of("Asia/Shanghai"));
         Instant instant4 = clock2.instant();
         System.out.println(instant4);
        //紐約時間
         Clock clock3 = Clock.system(ZoneId.of("America/New_York"));
         System.out.println("紐約時間: " + LocalDateTime.now(clock3));
         //不能用 .instant() 輸出 此輸出是系統默認時間
         //System.out.println(clock3.instant());



         //當前時區加上 100s
         Clock offset = Clock.offset(clock, Duration.ofSeconds(100));
         System.out.println(offset.instant());

ZoneId 和 ZonedDateTime

//默認時區時間
         ZonedDateTime now = ZonedDateTime.now();
         LocalDate localDate2 = now.toLocalDate();
         System.out.println(localDate2);//2019-08-24

         //特定時區下的日期和時間
         ZonedDateTime Shanghai = ZonedDateTime.of(LocalDateTime.now(), ZoneId.of("Asia/Shanghai"));
         System.out.println(Shanghai);//2019-08-24T23:22:31.149+08:00[Asia/Shanghai]

         ZonedDateTime Tokyo = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"));
         System.out.println(Tokyo);//2019-08-25T00:26:51.690+09:00[Asia/Tokyo]

         ZoneId america = ZoneId.of("America/New_York");
         System.out.println(ZonedDateTime.now(america));//2019-08-24T11:28:48.430-04:00[America/New_York]
使用 TemporalAdjuster 類靈活操縱日期
有的時候,你須要進行一些更加複雜的日期操做,好比,將日期調整到下個週日、下個工做日,或者是本月的最後一天。這時,你可使用重載版本的withXXX方法,向其傳遞一個提供了更多定製化選擇的TemporalAdjuster對象, 更加靈活地處理日期。對於最多見的用例,日期和時間API已經提供了大量預約義的 TemporalAdjuster。你能夠經過TemporalAdjuster類的靜態工廠方法訪問它們。
TemporalAdjuster類中的經常使用工廠方法
  • dayOfWeekInMonth 建立一個新的日期,它的值爲同一個月中每一週的第幾天
  • firstDayOfMonth 建立一個新的日期,它的值爲當月的第一天
  • firstDayOfNextMonth 建立一個新的日期,它的值爲下月的第一天
  • firstDayOfNextYear 建立一個新的日期,它的值爲明年的第一天
  • firstDayOfYear 建立一個新的日期,它的值爲當年的第一天
  • firstInMonth 建立一個新的日期,它的值爲同一個月中,第一個符合星期幾要求的值-
  • lastDayOfMonth 建立一個新的日期,它的值爲當月的最後一天
  • lastDayOfNextMonth 建立一個新的日期,它的值爲下月的最後一天
  • lastDayOfNextYear 建立一個新的日期,它的值爲明年的最後一天
  • lastDayOfYear 建立一個新的日期,它的值爲今年的最後一天
  • lastInMonth 建立一個新的日期,它的值爲同一個月中,最後一個符合星期幾要求的值
  • next/previous 建立一個新的日期,並將其值設定爲日期調整後或者調整前,第一個符合指定星 期幾要求的日期
  • nextOrSame/previousOrSame 建立一個新的日期,並將其值設定爲日期調整後或者調整前,第一個符合指定星 期幾要求的日期,若是該日期已經符合要求,直接返回該對象
//當月中 第二週 的週一
         TemporalAdjuster temporalAdjuster1 = TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.MONDAY);
         LocalDate with = LocalDate.now().with((temporal) -> temporal.with(temporalAdjuster1));
         System.out.println(with);//2019-08-12

         //firstDayOfMonth  當月的第一天
         TemporalAdjuster temporalAdjuster2 = TemporalAdjusters.firstDayOfMonth();
          with = LocalDate.now().with((temporal) -> temporal.with(temporalAdjuster2));
         System.out.println(with);//2019-08-1

         //firstDayOfNextYear  明年的第一天
         System.out.println(LocalDate.now().with((temporal -> temporal.with(TemporalAdjusters.firstDayOfNextYear()))));//2020-01-01

         /**
          * nextOrSame/previousOrSame 建立一個新的日期,
          * 並將其值設定爲日期調整後或者調整前,第一個符合指定星 期幾要求的日期,若是該日期已經符合要求,直接返回該對象
          */
         //今天是2019-08-25 週日 下一個週一 返回2019-08-26
         System.out.println(LocalDate.now().with((temporal -> temporal.with(TemporalAdjusters.nextOrSame(DayOfWeek.MONDAY)))));//2020-01-01
         //返回下一個第一個知足的指定日期 也就是 週四  第一個是 2019-08-29  第二個是 2019-09-05  可是返回一個知足的。
         System.out.println(LocalDate.now().with(TemporalAdjusters.next(DayOfWeek.THURSDAY)));//2019-08-29

java.util.Date 與 LocalDate、LocalTime、LocalDateTime 轉換

Date date1 = new Date();
         System.out.println("current date: " + date1);
         ZonedDateTime zonedDateTime = date1.toInstant().atZone(ZoneId.systemDefault());
         //Date -> LocalDate
         LocalDate localDate31 = zonedDateTime.toLocalDate();
         System.out.println(localDate31);//2019-08-24

         //Date -> LocalDate
         ZonedDateTime zonedDateTime3 = date1.toInstant().atZone(ZoneId.of("Asia/Shanghai"));
         LocalDate localDate32 = zonedDateTime3.toLocalDate();
         System.out.println(localDate32);//2019-08-24

         //Date -> LocalDateTime
         LocalDateTime localDateTime1 = zonedDateTime.toLocalDateTime();
         //Date -> LocalDateTime 另外一種方式
         LocalDateTime localDateTime2 = LocalDateTime.ofInstant(date1.toInstant(), ZoneId.systemDefault());


         //Date -> LocalTime
         LocalTime time1 = zonedDateTime.toLocalTime();

        //Calendar --> Instant
         Calendar.getInstance().toInstant();
jdk 8中 Date 類中引入了 2 個方法,from 和 toInstant
//LocalDateTime-> Date 方法 
         LocalDateTime localDateTime4 = LocalDateTime.now();
         System.out.println("localDateTime: " + localDateTime4);//2019-08-24T23:44:23.274

         //LocalDateTime-> Date 方法
         Date from2 = Date.from(localDateTime4.toInstant(ZoneOffset.UTC));
         Instant instant5 = from2.toInstant();
         System.out.println(from2);//Sun Aug 25 07:44:23 CST 2019
         System.out.println(instant5);//2019-08-24T23:44:23.274Z



         //// LocalDate -> Date
         LocalDate localDate3 = LocalDate.now();

         //先把  LocalDate -> LocalDateTime
         LocalDateTime localDateTime3 = localDate3.atStartOfDay();
         //再把 LocalDateTime -> Date
         Date from3 = Date.from(localDateTime3.toInstant(ZoneOffset.UTC));
         System.out.println(from3);
相關文章
相關標籤/搜索