由輸入資料取得資訊、相依日期

由日期字串,解析後取得部分或相依資訊。若輸入字串無法通過parse解析為Java LocalDate物件,抛出執行期例外。

int getYyy(input)
* 適用於:**YYYMMDD, YYYMM, YYY**
* 以數值格式取得民國年份,民國前一年(1911)的值為-1。
int getMm(input)
* 適用於:**YYYMMDD, YYYMM**
* 以數值格式取得月份。
int getDd(input)
* 適用於:**YYYMMDD**
* 以數值格式取得日。
String toYYYMM(input)
* 適用於:**YYYMMDD**
* '年月日'轉換為'年月'格式
String toYYY(input)
* 適用於:**YYYMMDD**
* '年月日'、'年月'轉換為'年'格式
LocalDate firstDay(yyymm) / firstDay(yyymm,days)
* 適用於:**YYYMM**
* 取得當月的第N天。
LocalDate lastDay(yyymm) / lastDay(yyymm,days)
* 適用於:**YYYMM**
* 取得當月的倒數第N天。
String relativeDate (yyymmdd, ChronoUnit, amount)
  • 適用於:YYYMMDD
  • 取得相對日期的表示字串
  • 時間單位使用JDK8的ChronoUnit
String previousDate
String nextDate
  • 適用於:YYYMMDD
  • 取得前一日/後一日的表示字串
String previousMonth
String nextMonth
  • 適用於:YYYMM
  • 取得後一月/後一月的表示字串

日期計數

  • 原則上建議先檢查輸入,要求 day1 ≦ day2,對於一般使用邏輯而言,可能較為容易轉換概念。
    • 這樣一來,大部分應用就可以把回傳值小於 0 (day1 > day2) 視作輸入錯誤。
  • 當 day1 ≦ day2 時,回傳值大於 0
    • 計數區段為:[day1 00:00 ~ day2 24:00]
      • 例如計算出境日數,xxx/03/01 出發 ~ xxx/03/01 當日返程就算一天。
      • 例如計算薪資日數,也是頭尾都算。
  • 當 day1 > day2 時,回傳值小於 0

    • 計數區段為:[day2 00:00 ~ day1 00:00]
      • 例如:繳費截止日 xxx/03/20,xxx/03/21 繳費為延遲一日(-1)
      • countDays(date, deadline)
  • 回傳值永不為 0。

long countDays(day1,day2)
* 適用於:**YYYMMDD**
* 計算涵蓋日數。
  * start/stop 同日為 1 、stop 晚於 start 一日為 2 。
  * stop 早於 start 一日為-1… 也就是 回傳值永不為 0 
  * 大部分應用可以把回傳值小於0 (stop<start) 視作輸入錯誤。
* 與一般Utility、Period.between的邏輯略有不同。
``` java
@Test
public void testCountDaysByString() {
    // 前一日:980803~980802
    assertEquals(-1, YYYMMDDUtils.countDays("0980803", "0980802"));  
    // 同日:980803~980803
    assertEquals(1, YYYMMDDUtils.countDays("0980803", "0980803"));   
    assertEquals(2, YYYMMDDUtils.countDays("0980803", "0980804"));   
    // 同月份測試:980803~980823
    assertEquals(21, YYYMMDDUtils.countDays("0980803", "0980823"));  
    // 跨月份測試:980803~980923
    assertEquals(52, YYYMMDDUtils.countDays("0980803", "0980923"));  
    // 跨年度測試:980803~990803
    assertEquals(366, YYYMMDDUtils.countDays("0980803", "0990803")); 
}
```    
float countMonths (day1,day2)
long countMonths (month1,month2)
* 適用於:**YYYMMDD, YYYMM**
* 計算涵蓋月數,原則同 countDays(),同月算一月、前一月為-1。

* YYYMMDD 回傳 float,前後未滿一月部分,依日數比例計算。
  ``` java
    // 同月份
    assertEquals(1 / 30.0, YYYMMDDUtils.countMonths("1070401", "1070401"));
    assertEquals(2 / 30.0, YYYMMDDUtils.countMonths("1070401", "1070402"));
    // 同月份/反向
    assertEquals(-1 / 30.0, YYYMMDDUtils.countMonths("1070402", "1070401"));
    // 跨月份
    assertEquals((2 / 31.0) + (1 / 30.0), YYYMMDDUtils.countMonths("1070330", "1070401"));
    assertEquals((2 / 31.0) + (2 / 30.0), YYYMMDDUtils.countMonths("1070330", "1070402"));
    assertEquals((2 / 31.0) + 2 + (2 / 30.0), YYYMMDDUtils.countMonths("1070330", "1070602"));
    assertEquals(1 + (1 / 30.0), YYYMMDDUtils.countMonths("1070301", "1070401"));
    assertEquals(2, YYYMMDDUtils.countMonths("1070301", "1070430"));

    // 跨月份/反向 : 四月未列計。
    assertEquals((-1 / 31.0), YYYMMDDUtils.countMonths("1070401", "1070331"));
    // 跨月份/反向 : 四月未列計。
    assertEquals((-2 / 31.0), YYYMMDDUtils.countMonths("1070401", "1070330"));
    // 跨月份/反向 : 4/1 一天、3/30、3/31 兩天。
    assertEquals((-2 / 31.0) + (-1 / 30.0), YYYMMDDUtils.countMonths("1070402", "1070330"));
    // 跨月份/反向 : 四月未列計。
    assertEquals(-1, YYYMMDDUtils.countMonths("1070401", "1070301"));
    // 跨月份/反向 : 四月的29天 加上 整個三月。
    assertEquals((-29 / 30.0) - 1, YYYMMDDUtils.countMonths("1070430", "1070301"));      
  ```

TODO : 有考慮增加的 METHOD : int age(birthday,now)

results matching ""

    No results matching ""