java8之LocalDate方法的用法研究

  前言:字字看來皆是血,幾天辛苦不尋常,花了幾天把LocalDate的方法研究了個遍,其中不乏自己的思考

說明鏈接:java.util.time包的描述

/**
 * 
 */
package com.ljh.myo2o.dao;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Month;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.time.temporal.TemporalQueries;
import java.time.temporal.ValueRange;
import java.util.Arrays;
import java.util.Locale;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @description:
 * @author :林建輝
 * @CreateTime:2018-11-23 02:23:41
 */
public class DateAndTimeDemo {
	private Logger logger = LoggerFactory.getLogger(DateAndTimeDemo.class);

	/**
	 * discription:
	 * 
	 * @author:林建輝
	 * @createTime:2018-11-23 02:23:41
	 * @param args
	 */
	public static void main(String[] args) {
		// 從默認時區的系統時鐘獲取當前日期
		// LocalDate:只包含日期而沒有時間
		// 該類重寫了toString()方法,所以打印的時候是以yyyy-MM-dd 格式輸出
		LocalDate today = LocalDate.now();
		// 今天的日期是: 2018-11-23
		System.out.println("今天的日期是: " + today);
		// 從指定的年月日中獲取LocalDate實例
		// 指定的日必須對年和月有效否則將拋出DateTimeException
		// 此方法有一個重載,就是第二個參數爲Month枚舉
		LocalDate specifiedDate = LocalDate.of(2018, 1, 1);
		LocalDate sDate = LocalDate.of(2018, Month.JANUARY, 1);
		// 判斷兩個日期是否相等就用equals方法,LocalDate類重寫了equals方法
		System.out.println(specifiedDate.equals(sDate));// true
		// 如果想知道某一年的第340天是幾月幾號,可以使用下面的方法
		LocalDate date = LocalDate.ofYearDay(2018, 340);
		System.out.println(date);// 2018-12-06
		// 如果想知道今天是一年中的第幾天,可以使用下面的方法,其它同理
		int dayOfYear = date.getDayOfYear();
		int dayOfMonth = date.getDayOfMonth();
		System.out.println(dayOfYear + "__" + dayOfMonth);
		// 下面是java.util.time包中唯二的兩個枚舉
		// 不僅有枚舉值,也包含一些計算方法如:plus/minus/firstMonthOfQuarter
		DayOfWeek dayOfWeek = date.getDayOfWeek();
		Month month = date.getMonth();
		// 獲取月份可以使用以下方法
		int monthValue = month.getValue();
		int monthValue2 = date.getMonthValue();
		// 獲取該月份有多少天
		date.lengthOfMonth();
		month.length(date.isLeapYear());// leap year 閏年

		// EpochDay:紀元日 ,第0天是1970-01-01天,負數代表早些日子
		long epochDayNums = date.toEpochDay();
		LocalDate.ofEpochDay(epochDayNums);
		// Chronology:年表
		// LocalDate dateNow = date.getChronology().dateNow();

		// TemporalAccessor是所有時間類以及時間接口的父類
		// LocalDate from = LocalDate.from(TemporalAccessor temporal);

		// System.out.println(LocalDateTime.now().toString().replace("T", " "));

		// 靜態方法的引用中的返回值類型就是功能函數裏的泛型,該靜態方法的參數就是功能函數中方法的參數
		// TemporalQuery<LocalDate> q=LocalDate::from;

		// 其內部就是調用其重載方法
		LocalDate parse1 = LocalDate.parse("2018-11-11");
		LocalDate parse2 = LocalDate.parse("2018-11-11", DateTimeFormatter.ISO_LOCAL_DATE);
		System.out.println(parse1);
		System.out.println(parse2);

		// 雖然不知道有什麼用,用於判斷
		boolean supportedChronoField = date.isSupported(ChronoField.DAY_OF_MONTH);
		boolean supportedChronoUnit = date.isSupported(ChronoUnit.YEARS);
		System.out.println(supportedChronoField);
		System.out.println(supportedChronoUnit);

		// 獲取某個日期字段的有效範圍值
		ValueRange range = date.range(ChronoField.DAY_OF_MONTH);
		System.out.println(range);// 1 - 31

		// int i = date.get(ChronoField.DAY_OF_MONTH);//6
		// 反正也不知道啥用
		// 哪種寫法更牛逼點
		/*
		 * for (ChronoField c : ChronoField.values()) { if (date.isSupported(c))
		 * { if ("EpochDayProlepticMonth".contains(c.toString())) {
		 * System.out.println(date.getLong(c)+"--"+c); }else {
		 * System.out.println(date.get(c)+"--"+c); }
		 * 
		 * } }
		 */
		Arrays.asList(ChronoField.values()).forEach((c) -> {
			if (date.isSupported(c)) {
				if ("EpochDayProlepticMonth".contains(c.toString())) {
					System.out.println(date.getLong(c) + "--" + c);
				} else {
					System.out.println(date.get(c) + "--" + c);
				}
			}
		});

		// with系列方法
		/*
		 * LocalDate with(TemporalAdjuster adjuster) LocalDate
		 * with(TemporalField field, long newValue) LocalDate withYear(int year)
		 * LocalDate withMonth(int month) LocalDate withDayOfYear(int dayOfYear)
		 * 由於LocalDate 是final類,每次的修改都要用變量保存起來 示例表示返回7月份的最後一天的日期 result =
		 * localDate.with(JULY).with(lastDayOfMonth());
		 */
		// LocalDate withDayOfMonth =
		// date.with(Month.JULY).withDayOfMonth(Month.JULY.length(date.with(Month.JULY).isLeapYear()));
		LocalDate lastDateOfJuly = date.with(Month.JULY);
		lastDateOfJuly = lastDateOfJuly.withDayOfMonth(lastDateOfJuly.lengthOfMonth());
		System.out.println(lastDateOfJuly);

		/*
		 * // these two lines are equivalent 
		 * Period period = start.until(end); 
		 * Period.between(start, end);
		 */

		/*
		 * plus和minus系列方法: Period類和Duration類實現了TemporalAmount接口
		 * ChronoUnit實現了TemporalUnit接口 LocalDate plus(TemporalAmount
		 * amountToAdd) LocalDate plus(long amountToAdd, TemporalUnit unit)
		 * LocalDate plusYears(long yearsToAdd) LocalDate plusMonths(long
		 * monthsToAdd) LocalDate plusWeeks(long weeksToAdd) LocalDate
		 * plusDays(long daysToAdd)
		 */
		Period period = Period.between(LocalDate.of(2018, 12, 7), LocalDate.of(2018, 12, 31));
		LocalDate plusDate = date.plus(period);
		System.out.println(plusDate);
		
	      System.out.printf("LocalDate precision is %s%n",
	         date.query(TemporalQueries.precision()));
	      
	      /*
	       * 插曲
	      StringBuilder sb = new StringBuilder();//實現了Appendable接口
	      //格式輸出到Appendable,以中國的格式輸出
	      Formatter formatter = new Formatter(sb, Locale.CHINA);
	     //格式輸出語法: %[argument_index$][flags][width][.precision]conversion
	      formatter.format("%4$2s%3$2s%2$2s%1$2s", "a", "b", "c", "d");
	      System.out.println(formatter.out());
	      formatter.format(Locale.PRC, "e = %+.4f", Math.E);
	      System.out.println(formatter.out());
	      formatter.close();
	      
	      String format = String.format("hello,%s","world!");
	      System.out.println(format);
	      	
	      System.out.format("hello,%s","world!");*/
	      
	      //沒有得到預期效果
	      LocalDate newDate =(LocalDate)date.adjustInto(LocalDate.of(2018, 12, 31));
	      System.out.println("newDate:"+newDate);
	      
	      //這樣調整就行
	      LocalDate with = LocalDate.now().with(TemporalAdjusters.next(DayOfWeek.MONDAY));
	      System.out.println(with);//今天的日期爲25號,調整後的日期爲2018-11-26
	     
	      //計算距離2019-01-30有多少天
	      long until = LocalDate.now().until(LocalDate.of(2019, 1, 30), ChronoUnit.DAYS);
	      System.out.println(until);//66
	      
	      //until 的重載
	      Period period2 = LocalDate.now().until(LocalDate.of(2019, 1, 30));
	      System.out.println(period2.getDays());//爲什麼是5,這個方法有bug
	      
	      /*
	       * 從源碼裏可以看到,格式化就是調用DateTimeFormatter.format()方法
	       *  public String format(DateTimeFormatter formatter) {
        	 	Objects.requireNonNull(formatter, "formatter");
        	    return formatter.format(this);
    		  }
	       */
	      //寫個示例而已,雖然沒有必要這麼做
	      DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
	      DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd",Locale.CHINA);
	      String format = LocalDate.now().format(formatter);
	      System.out.println(format);
	      
	      /*
	       * atTime系列方法:用於調整時間,給日期加時間
	       * LocalDateTime atTime(LocalTime time)
	       * LocalDateTime atTime(int hour, int minute)
	       * LocalDateTime atTime(int hour, int minute, int second)
	       * LocalDateTime atTime(int hour, int minute, int second, int nanoOfSecond)
	       * OffsetDateTime atTime(OffsetTime time)
	       */
	      LocalDateTime atTime = LocalDate.now().atTime(10, 25);
	      System.out.println(atTime);//2018-11-25T10:25
	      //打印出來我們發現時間和日期多了個T,不符合中國的日期標準,格式化一下
	      String format2 = atTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
	      System.out.println(format2);//2018-11-25T10:25:00
	      //打印出來我們發現,使用預定格式的格式化器還是有個T,只是多了秒
	      //當預定格式的格式化器也無法滿足的時候,使用自定義的格式化器
	      DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
	      String format3 = atTime.format(dtf);
	      System.out.println(format3);//2018-11-25 10:25:00,完美解決
	      
	      //將時分秒歸零
	      LocalDateTime atStartOfDay = LocalDate.now().atStartOfDay();
	      String format4 = atStartOfDay.format(dtf);
	      System.out.println(format4);//2018-11-25 00:00:00
	      
	      /*
	       * int compareTo(ChronoLocalDate other)和boolean equals(Object obj)
	       * 有同樣的效果,都重寫了父類的方法
	       * 其實equals 方法就是調用了compareTo方法
	       */
	      if (LocalDate.now().equals(LocalDate.of(2018, 11, 25))) {
			System.out.println(true);
		  }
	      if (LocalDate.now().compareTo(LocalDate.of(2018, 11, 25))==0) {
				System.out.println(true);
		  }
	      
	      /*
	       * is系列方法:
	       * boolean isAfter(ChronoLocalDate other)
	       * boolean isBefore(ChronoLocalDate other)
	       * boolean isEqual(ChronoLocalDate other)
	       * 和上面的compareTo和equals方法是統一性質
	       */
	      //至此:大功告成,字字看來皆是血,幾天辛苦不尋常
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章