在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/Java/ java 獲取某個(gè)月的每周的開始日期和結(jié)束日期

java 獲取某個(gè)月的每周的開始日期和結(jié)束日期

給定某年某月(yyyy-MM), 獲取該月的每周的開始日期和結(jié)束日期(yyyy-MM-dd,每周周一為第一天,周日為最后一天),
比如給定2018-08,該月第一周為2018-08-01至2018-08-05,第二周為2018-08-06至2018-08-12,以此類推,最后一周為2018-08-27至2018-08-31,
再如2018-07,第一周為2018-07-01至2018-07-01,最后一周為2018-07-30至2018-07-31.
該如何求?

回答
編輯回答
乞許

Java8 LocalDate 了解一下

public static void main(String[] args) {
    
    // Java8  LocalDate   
    LocalDate date = LocalDate.parse("2018-08-01");
    
    // 該月第一天
    LocalDate firstDay = date.with(TemporalAdjusters.firstDayOfMonth());
    // 該月最后一天
    LocalDate lastDay = date.with(TemporalAdjusters.lastDayOfMonth());
    // 該月的第一個(gè)周一 
    LocalDate start = date.with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY));
    
    List<String> list = new ArrayList<>();
    
    // 處理每個(gè)月的1號(hào)不是周一的情況
    if (!firstDay.equals(start)) {
        
        StringBuilder strbur = new StringBuilder();
        strbur.append(firstDay.toString())
              .append("至")
              .append(start.plusDays(-1).toString());
        list.add(strbur.toString());
    }
    
    while (start.isBefore(lastDay)) {
        
        StringBuilder strbur = new StringBuilder();
        strbur.append(start.toString());
        
        LocalDate temp = start.plusDays(6);
        if (temp.isBefore(lastDay)) {
            
            strbur.append("至")
                  .append(temp.toString());
        } else {
            
            strbur.append("至")
                  .append(lastDay.toString());
        }
        
        list.add(strbur.toString());
        start = start.plusWeeks(1);
    }
    
    System.out.println(list.toString());
}
2018年6月9日 18:17
編輯回答
傻丟丟

請(qǐng)參考 java calender 類的使用,這個(gè)類可以滿足你的所有需求。用的時(shí)候注意時(shí)區(qū)以及冬令時(shí)和夏令時(shí)啊

2018年2月20日 15:23
編輯回答
陌璃

那你一周跨月的情況考慮到了嗎?

2017年5月23日 03:42
編輯回答
無(wú)標(biāo)題

題主,以下是我的思考思路,僅供參考:

讀完需求,感覺輸入輸出大體是這個(gè)樣子,
輸入:yyyy-MM年月日期一個(gè)
輸出:返回該年月所在月的所有周信息(每周的起始日期和結(jié)束日期)

既然是通過某一個(gè)月找到該月每周的起始日期、結(jié)束日期,那換句話說,一個(gè)月里有很多日期,這么日期它可以按照周來分類,第一周的日期為一類,第二周的日期為一類,以此類推,然后每一類中按照日期升序排序,我取第一個(gè)日期和最后一個(gè)日期最終就可以達(dá)到題主要求了,至此除了輸入輸出外,中間過程應(yīng)該是這個(gè)樣子

輸入:yyyy-MM年月日期一個(gè)

  1. yyyy-MM轉(zhuǎn)化為List<日期>
  2. List<日期>按照周進(jìn)行分類得到類似一個(gè)map的結(jié)果Map<Integer, List<日期>>(其中key就是第幾周)
  3. Map<Integer, List<日期>>中每一個(gè)List<日期>取第一個(gè)值得到該周的第一天,取最后一個(gè)值得到該周的最后一天

輸出:返回該年月所在月的所有周信息(每周的起始日期和結(jié)束日期)

有了以上一個(gè)步驟,我們?cè)賮硪灰唤鉀Q步驟需要用到的代碼,當(dāng)然我這里沒有選擇用 java calender 類,emmm,我覺得它們實(shí)在太臃腫了,也容易犯錯(cuò),API也不太好用,就以Java8的新時(shí)間API來替代了

Java8的新時(shí)間API中,以前表示一個(gè)時(shí)間的龐大齊全的Date類被拆分了成了很多類(以前一個(gè)Date對(duì)象既表現(xiàn)了日期,也表現(xiàn)了時(shí)間,也表現(xiàn)了時(shí)區(qū),大而全但不好用),這里我們要用到的是僅表示日期的YearMonth(yyyy-MM)和LocalDate(yyyy-MM-dd),YearMonth就表達(dá)一個(gè)年月,LocalDate就表達(dá)一個(gè)年月日

所以上訴需求立馬轉(zhuǎn)換為

輸入:YearMonth年月日期一個(gè)

  1. YearMonth轉(zhuǎn)化為List<LocalDate>
  2. List<LocalDate>按照周進(jìn)行分類得到類似一個(gè)map的結(jié)果Map<Integer, List<LocalDate>>(其中key就是第幾周可以)
  3. Map<Integer, List<LocalDate>>中每一個(gè)List<LocalDate>取第一個(gè)值得到該周的第一天,取最后一個(gè)值得到該周的最后一天

輸出:返回該年月所在月的所有周信息(每周的起始日期和結(jié)束日期)

由于最終我們是在List<LocalDate>中取第一個(gè)日期和最后一個(gè)日期作為最終返回結(jié)果,因此套用那句我不知道在哪里看到的話:引用新的編程元素,可以增加代碼的可讀性,所以我們加一個(gè)新的類型WeekData來表示這么一個(gè)返回結(jié)果

static class WeekData{
        // 一周的開始時(shí)間
        private LocalDate start;
        // 一周的結(jié)束時(shí)間
        private LocalDate end;

        public WeekData(List<LocalDate> localDates) {
            this.start = localDates.get(0);
            this.end = localDates.get(localDates.size()-1);
        }

        @Override
        public String toString() {
            return "開始時(shí)間:" + this.start + ",結(jié)束時(shí)間:" + this.end;
        }
    }

所以上訴需求立馬轉(zhuǎn)換為
輸入:YearMonth年月日期一個(gè)

  1. YearMonth轉(zhuǎn)化為List<LocalDate>
  2. List<LocalDate>按照周進(jìn)行分類得到類似一個(gè)map的結(jié)果Map<Integer, WeekData>(其中key就是第幾周可以)

輸出:返回該年月所在月的所有周信息(每周的起始日期和結(jié)束日期)

現(xiàn)在就可以來解決每個(gè)步驟代碼了,這樣一個(gè)轉(zhuǎn)換的方法,初始狀態(tài)肯定是這樣YearMonth作為傳參,返回一個(gè)Map<Integer, WeekData>

private static Map<Integer, WeekData> weeks(YearMonth yearMonth){
     // TODO
}

第一個(gè)步驟,YearMonth轉(zhuǎn)化為List<LocalDate>,表示的是這個(gè)月的所有日期,這種List<LocalDate>的,我第一想法就是用Java8stream,首先根據(jù)yearMonth獲得這個(gè)月的開始日期和結(jié)束日期,用LocalDatewith方法即可,with就是調(diào)整的意思,想啥調(diào)整就咋調(diào)整非常靈活,隨便取一個(gè)日期(我這里取的是但當(dāng)前日期)

private static Map<Integer, WeekData> weeks(YearMonth yearMonth){
        LocalDate start = LocalDate.now().with(yearMonth).with(TemporalAdjusters.firstDayOfMonth());
        LocalDate end = LocalDate.now().with(yearMonth).with(TemporalAdjusters.lastDayOfMonth());
}

完成。。。是很簡(jiǎn)單吧,還有封裝好的TemporalAdjusters.firstDayOfMonth()TemporalAdjusters.lastDayOfMonth()

接下來我們來構(gòu)造stream,用Stream.iterate(start, localDate -> localDate.plusDays(1l))構(gòu)造一個(gè)無(wú)限流,它代表,以start作為起始值,按照第二個(gè)參數(shù)localDate -> localDate.plusDays(1l)也就是加一天的方式構(gòu)造一個(gè)無(wú)限流,當(dāng)然我要的不是無(wú)限,而是要到這個(gè)月末,所以limit(ChronoUnit.DAYS.between(start, end) + 1),這樣就把這個(gè)無(wú)限流截?cái)嗔?/p>

private static Map<Integer, WeekData> weeks(YearMonth yearMonth){
        LocalDate start = LocalDate.now().with(yearMonth).with(TemporalAdjusters.firstDayOfMonth());
        LocalDate end = LocalDate.now().with(yearMonth).with(TemporalAdjusters.lastDayOfMonth());

        List<LocalDate> localDates = Stream.iterate(start, localDate -> localDate.plusDays(1l))
                .limit(ChronoUnit.DAYS.between(start, end) + 1)
                .collect(Collectors.toList());
}

這樣第一步就完成了,第二步,按周分類,這里有一個(gè)知識(shí)點(diǎn),給一個(gè)LocalDate對(duì)象,怎么判斷它是該月的第幾周,這里肯定要用LocalDateget方法,因?yàn)檫@個(gè)方法就是表示從當(dāng)前日期中獲取某個(gè)屬性值,參數(shù)是接口TemporalField,你需要傳入一個(gè)實(shí)現(xiàn)類即可,這個(gè)實(shí)現(xiàn)類就是定義了這個(gè)屬性,當(dāng)然JDK默認(rèn)有一個(gè)實(shí)現(xiàn)類枚舉ChronoField,里面有很多好用的實(shí)現(xiàn)類可以用,所以很容易就會(huì)選到一個(gè)枚舉ChronoField.ALIGNED_WEEK_OF_MONTH,看起來好像是對(duì)的,ALIGNED不認(rèn)識(shí),WEEK_OF_MONTH感覺意思很明白,貌似能用,其實(shí)不然,這個(gè)實(shí)現(xiàn)類定義的一周跟我們想象中的不一樣,它的一周是按照完整7天來算的,拿8月6號(hào)來看,我們感覺是第二周,但是實(shí)際結(jié)果是第一周,因?yàn)橐獫M打滿算的7天才算一周,8月6號(hào)還是算第一周的第六天而已

clipboard.png

所以得換個(gè)方法,ChronoField.ALIGNED_WEEK_OF_MONTH是按照周的一共7天這個(gè)維度來定義周,但是跟我們想要的周定義不太一樣,我們定義的周,例如8月,前面的5天就應(yīng)該是第一周了,也就是說,我們想象的周,不是說幾天是一周,應(yīng)該是周一是一周的開始,周日是一周的結(jié)束,就算只有一個(gè)周日,那也是一周,所以我們就看到另一個(gè)類WeekFields其中的靜態(tài)變量SUNDAY_START

clipboard.png

從注釋來看是我們要的,不過是以星期天為一周開始的(這是國(guó)外的默認(rèn)了,國(guó)內(nèi)還是以周一為第一周開始的),所以我們直接用它的方式來構(gòu)造一個(gè)就可以啦

localDate.get(WeekFields.of(DayOfWeek.MONDAY, 1).weekOfMonth()

最后完整的就是

private static Map<Integer, WeekData> weeks(YearMonth yearMonth){
        LocalDate start = LocalDate.now().with(yearMonth).with(TemporalAdjusters.firstDayOfMonth());
        LocalDate end = LocalDate.now().with(yearMonth).with(TemporalAdjusters.lastDayOfMonth());

        Map<Integer, WeekData> map = Stream.iterate(start, localDate -> localDate.plusDays(1l))
                .limit(ChronoUnit.DAYS.between(start, end)+1)
                .collect(Collectors.groupingBy(localDate -> localDate.get(WeekFields.of(DayOfWeek.MONDAY, 1).weekOfMonth()),
                                Collectors.collectingAndThen(Collectors.toList(), WeekData::new)));
        return map;
    }

最后用了哈Collectors.groupingByCollectors.collectingAndThen配合了下,總之還算是比較簡(jiǎn)潔的寫法,希望能幫到你

最后簡(jiǎn)單打印哈獲得map,看看結(jié)果

clipboard.png

2018年3月14日 02:36
編輯回答
尐飯團(tuán)
package com.blog.web.front;


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class Test{
    /**
     * 演示用
     * @param date
     * @param format
     * @return
     */
    public static String formatDate(Date date,String format){
        if(null == format || "".equals(format.trim())){
            format = "yyyy-MM-dd";
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        return dateFormat.format(date);
    }
    /**
     * 演示用
     * @param dateStr
     * @param format
     * @return
     */
    public static Date parseDate(String dateStr,String format){
        if(null == format || "".equals(format.trim())){
            format = "yyyy-MM-dd";
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        try {
            return dateFormat.parse(dateStr);
        } catch (ParseException e) {
            return null;
        }
    }
    
    public static List<String[]> getAllWeek(String dateStr){
        Date date = parseDate(dateStr,"yyyy-MM");
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.DAY_OF_MONTH, 1);
        int dayOfWeek = c.get(Calendar.DAY_OF_WEEK) - 1;
        dayOfWeek = dayOfWeek == 0 ? 7 : dayOfWeek; 
        int days = c.getActualMaximum(Calendar.DAY_OF_MONTH);
        List<String[]> result = new ArrayList<String[]>();
        String[] array = null;
        for(int curDay = 1;curDay <= days;curDay++){
            c.set(Calendar.DAY_OF_MONTH, curDay);
             if(1 == curDay || 1 == dayOfWeek){
                 array = new String[2];
                 array[0] = formatDate(c.getTime(),null);
             }
             if(dayOfWeek == 7 || curDay == days){
                 array[1] = formatDate(c.getTime(),null);
                 result.add(array);
                 dayOfWeek = 0;
             }
             dayOfWeek++;
        }
        return result;
    }
    
    public static void main(String[] args) {
        List<String[]> result = getAllWeek("2018-07");
        String[] weekPrefixArray = new String[]{"一","二","三","四","五","六","七","八"};
        for(int i = 0;i < result.size();i++){
            String arr[] = result.get(i);
            System.out.println("第"+weekPrefixArray[i]+"周為"+arr[0]+ "至" + arr[1]);
        }
    }
}

大概思路吧,代碼寫的不嚴(yán)謹(jǐn),看看吧。

2017年9月10日 15:32