1.說明: 業務要求,需要知道一個日期是哪個月份的第幾周,並且是周一為一周的開始,周一在哪個月,此周就是屬於哪個月的;
比如:
2020-02-01 和 2020-02-02屬於1月份的第四周 ;
2020-02-03 屬於2月份第一周
2.思路: 都2020年了,我們使用JDK8的LocalDate 吧,畢竟真香! API好用~
①找到查詢日期sourceTime的當月的第一天(firstDayOfMonth),比如2020-02-01,
②從月初firstDayOfMonth開始找到周一(firstMondayOfMonth)
③比較sourceTime是否 >= firstMondayOfMonth;
④如果true,表示sourceTime就是在當月的周,直接計算firstMondayOfMonth和sourceTime相隔天數,除以7后+1來計算是第幾周;
⑤如果false,表示sourceTime就是在上月的周,需要計算上月的第一個周一(firstMondayOfMonth_last),並計算sourceTime和firstMondayOfMonth_last相隔天數,除以7后+1來計算是上月第幾周;
⑥return
3.代碼如下
獲取某個時間的月份第一天(網上copy的)
/** * java8(經測試別的版本獲取2月有bug) 獲取某月第一天的00:00:00 * * @return */ public static LocalDateTime getFirstLocalDayOfMonth(LocalDateTime localDateTime) { return localDateTime.with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN); }
獲取漢字版月份(這個是自己的笨法子)
/** * 獲取漢字版月份 * * @param monthNo 第幾月 * @return */ public static String getMonthChinese(int monthNo) { switch (monthNo) { case 1: return "一"; case 2: return "二"; case 3: return "三"; case 4: return "四"; case 5: return "五"; case 6: return "六"; case 7: return "七"; case 8: return "八"; case 9: return "九"; case 10: return "十"; case 11: return "十一"; case 12: return "十二"; default: break; } return null; }
獲取幾月份的第幾周(核心方法)
/** * 獲取幾月份的第幾周 [X月份第X周] * * @param sourceTime 這個推薦取00:00:00時間 * @return */ public static Map<String, Object> getMonthNoAndWeekNo(LocalDateTime sourceTime) { Map<String, Object> map = new HashMap<>(); String monthNoAndWeekNo = null; //獲取當月的第一天 LocalDateTime firstDayOfMonth = getFirstLocalDayOfMonth(sourceTime); //獲取月第一天開始的周一,從當月第一天開始找 LocalDateTime firstMondayOfMonth = firstDayOfMonth; for (int i = 0; i < 6; i++) { DayOfWeek dayOfWeekTemp = firstMondayOfMonth.getDayOfWeek(); if (dayOfWeekTemp.equals(DayOfWeek.MONDAY)) { break; } //往后推一天 firstMondayOfMonth = firstMondayOfMonth.plusDays(1); } //比較當月的第一個星期一 < = 參數時間 if (!firstMondayOfMonth.isBefore(sourceTime)) { //如果當月的第一個周一大於參數時間,則要計算到上個月份去 //獲取上一個月的第一個周一 LocalDateTime lastMontLocalDateTime = sourceTime.minusMonths(1); //上個月的第一天 LocalDateTime firstDayOfMonth_last = getFirstLocalDayOfMonth(lastMontLocalDateTime); //從上個月的第一天開始找周一 LocalDateTime firstMondayOfMonth_last = firstDayOfMonth_last; for (int i = 0; i < 6; i++) { DayOfWeek dayOfWeekTemp = firstMondayOfMonth_last.getDayOfWeek(); if (dayOfWeekTemp.equals(DayOfWeek.MONDAY)) { break; } //往后推一天 firstMondayOfMonth_last = firstMondayOfMonth_last.plusDays(1); } // 計算兩個時間間隔天數 (上月第一個周一 減去 當前時間) Duration duration = Duration.between(firstMondayOfMonth_last, sourceTime); long diffDays = duration.toDays(); //相差的天數 //第幾周weekNo long weekNo = (diffDays / 7) + 1; //月份 int monthNo = firstMondayOfMonth_last.getMonth().getValue();//漢字版月份 String monthChinese = getMonthChinese(monthNo); monthNoAndWeekNo = monthChinese + "月份" + "第" + weekNo + "周"; map.put("monthNo", monthNo); map.put("weekNo", weekNo); map.put("monthNoAndWeekNo", monthNoAndWeekNo); } else { //當月第一個周一在當前時間之前 firstMondayOfMonth<=sourceTime //計算兩個時間間隔天數 int dayOfMonthFirstMonday = firstMondayOfMonth.getDayOfMonth(); int dayOfMonthSourceTime = sourceTime.getDayOfMonth(); int diffDays = dayOfMonthSourceTime - dayOfMonthFirstMonday; //第幾周weekNo int weekNo = (diffDays / 7) + 1; //月份 int monthNo = sourceTime.getMonth().getValue(); map.put("monthNo", monthNo); map.put("weekNo", weekNo); //漢字版月份 String monthChinese = getMonthChinese(monthNo); monthNoAndWeekNo = monthChinese + "月份" + "第" + weekNo + "周"; map.put("monthNoAndWeekNo", monthNoAndWeekNo); } return map; }
4.測試
public static void main(String[] args) { DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); LocalDateTime sourceTime = LocalDateTime.parse("2020-02-03 17:07:05", df); Map<String, Object> weekNoOfMonth = getMonthNoAndWeekNo(sourceTime); System.out.println("weekNoOfMonth :" + weekNoOfMonth); LocalDateTime sourceTime2 = LocalDateTime.parse("2020-02-16 17:07:05", df); Map<String, Object> weekNoOfMonth2 = getMonthNoAndWeekNo(sourceTime2); System.out.println("weekNoOfMonth2 :" + weekNoOfMonth2); LocalDateTime sourceTime3 = LocalDateTime.parse("2020-02-01 17:07:05", df); Map<String, Object> weekNoOfMonth3 = getMonthNoAndWeekNo(sourceTime3); System.out.println("weekNoOfMonth3 :" + weekNoOfMonth3); }
結果如下:
weekNoOfMonth :{monthNo=2, weekNo=1, monthNoAndWeekNo=二月份第1周} weekNoOfMonth2 :{monthNo=2, weekNo=2, monthNoAndWeekNo=二月份第2周} weekNoOfMonth3 :{monthNo=1, weekNo=4, monthNoAndWeekNo=一月份第4周}
5.總結
上面邏輯應該可以優化~