簡體   English   中英

哪幾個星期與哪個月相關?

[英]Which weeks are associated with which months?

JodaTime有沒有辦法輕松確定哪個星期屬於哪個月?

給出月份數的東西會返回與之相關的一周中的幾周。 一個星期應與特定月份相關聯,如果其中有4天以上。

In 2014 for month = 1 then weeks = [1, 2, 3, 4, 5] (note 5 weeks because of 4 days rule)
In 2014 for month = 3 then weeks = [10, 11, 12, 13] (note 4 weeks because of same rule)

我不想計算'手動'......

您必須為指定的周數實例化DateTime對象,然后只讀取其月份屬性 (使用Joda-TimeGoogle Guava )。

        DateTime dateTime = new DateTime().withWeekOfWeekyear(i).withDayOfWeek(DateTimeConstants.MONDAY);
        if (dateTime.dayOfMonth().getMaximumValue() - dateTime.dayOfMonth().get() < 3) {
            dateTime = dateTime.plusMonths(1);
        }
        int month = dateTime.monthOfYear().get();

我們還可以使用以下功能打印屬於他們的所有月份:

public static void main(String[] args) {
    Multimap<Integer, Integer> monthsWithWeeks = LinkedListMultimap.create();

    int weeksInYear = new DateTime().withYear(2014).weekOfWeekyear().getMaximumValue();
    for (int i = 1; i <= weeksInYear; i++) {
        DateTime weekDate = new DateTime().withWeekOfWeekyear(i).withDayOfWeek(DateTimeConstants.MONDAY);
        if (weekDate.dayOfMonth().getMaximumValue() - weekDate.dayOfMonth().get() < 3) {
            weekDate = weekDate.plusMonths(1);
        }
        int month = weekDate.monthOfYear().get();
        monthsWithWeeks.put(month, i);
    }

    for (Integer month : monthsWithWeeks.keySet()) {
        System.out.println(String.format("%d => [%s]", month, Joiner.on(',').join(monthsWithWeeks.get(month))));
    }
}

有趣的問題,雖然我對Joda的經驗較少。 我試圖用jata.util解決它與簡單計算的類,我想它解決了你的問題 - 只有沒有Joda。

累積一年中一個月的所有周數的方法:

public static Integer[] getWeeksInMonth(int month, int year) {
    List<Integer> list = new ArrayList<Integer>();
    SimpleDateFormat format = new SimpleDateFormat("w");

    Calendar startDate = Calendar.getInstance();
    Calendar endDate = Calendar.getInstance();

    startDate.set(year, month - 1, 1);
    startDate.setMinimalDaysInFirstWeek(4);

    endDate.set(year, month, 0);

    // Iterate between the start and stop days
    while (startDate.getTimeInMillis() <= endDate.getTimeInMillis()) {

        Calendar cal = Calendar.getInstance();
        cal.setTime(startDate.getTime());
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        // System.out.println("Here here " +
        // cal.get(Calendar.DAY_OF_MONTH));

        // Start of the week is Monday - check if dates 1, 2, 3 fall after
        // Wednesday (specified 4 day rule)
        if ((startDate.get(Calendar.DAY_OF_WEEK) > Calendar.THURSDAY)
                && (startDate.get(Calendar.DAY_OF_MONTH) < 4)) {

            // If they do, move the dates to next immediate start of the
            // week - making it to 4th
            startDate.add(Calendar.DAY_OF_MONTH,
                    (4 - startDate.get(Calendar.DAY_OF_MONTH)));

            // Similarly - check if last dates of the month make less than 4
            // for that month
        } else if ((startDate.get(Calendar.DAY_OF_MONTH) > 25)
                && ((startDate.getActualMaximum(Calendar.DAY_OF_MONTH) - (cal
                        .get(Calendar.DAY_OF_MONTH))) + 1) < 4) {
            // If they do, move the dates to next immediate start of the
            // week - making it to next month

            startDate
                    .add(Calendar.DAY_OF_MONTH,
                            (startDate
                                    .getActualMaximum(Calendar.DAY_OF_MONTH) - startDate
                                    .get(Calendar.DAY_OF_MONTH)) + 1);

        } else {
            // Get the number of the week
            // System.out.println(startDate.getTime());
            int week = Integer.parseInt(format.format(startDate.getTime()));

            // If December, check if the next year's 1st week falls under
            // the 4 day rule, if it does then ignore
            if (!(startDate.get(Calendar.MONTH) == Calendar.DECEMBER && week == 1))
                list.add(week);

            startDate.add(Calendar.WEEK_OF_MONTH, 1);
        }
    }

    return list.toArray(new Integer[list.size()]);
}

調用main方法:

public static void main(String... args) {
        int year = 2014;
        System.out.println(":::: YEAR " + year + " ::::");
        for (int j = 1; j <= 12; j++) {
            Integer[] array = getWeeksInMonth(j, year);
            System.out.print("For month : " + j);
            System.out.print(" [ ");
            for (int i = 0; i < array.length; i++) {
                System.out.print(array[i] + " ");
            }
            System.out.print("]");
            System.out.println();
        }
    }

輸出(可能的測試用例):

:::: YEAR 2014 ::::
For month : 1 [ 1 2 3 4 5 ]
For month : 2 [ 6 7 8 9 ]
For month : 3 [ 10 11 12 13 ]
For month : 4 [ 14 15 16 17 ]
For month : 5 [ 18 19 20 21 22 ]
For month : 6 [ 23 24 25 26 ]
For month : 7 [ 27 28 29 30 31 ]
For month : 8 [ 32 33 34 35 ]
For month : 9 [ 36 37 38 39 ]
For month : 10 [ 40 41 42 43 44 ]
For month : 11 [ 45 46 47 48 ]
For month : 12 [ 49 50 51 52 ]

您可以驗證其他測試用例,並告訴我是否有任何問題。 我知道很多計算,但它對要求很靈活。

使用JodaTime時非常簡單:

/** returns first and last week in a month (must have at least 4 days of that week)
 *  Warning: The first week might be week 53 
 */
public static int[] firstAndLastWeeksInMonth(int year, int month) {
    int firstweek = new LocalDate(year, month, 4).getWeekOfWeekyear();
    int lastweek = new LocalDate(year, month, 1).plusMonths(1).minusDays(4).getWeekOfWeekyear();
    return new int[] { firstweek, lastweek };
}

public static List<Integer> weeksInMonth(int year, int month) {
    int[] fl = firstAndLastWeeksInMonth(year, month);
    ArrayList<Integer> weeks = new ArrayList<Integer>(4);
    weeks.add(fl[0]);
    for( int w = fl[0] > fl[1] ? 1 : fl[0] + 1; w <= fl[1]; w++ )
        weeks.add(w);
    return weeks;
}

一些幫助代碼,用於測試:

static void testWeeksInMonth(int year, int month, boolean printdetail) {
        List<Integer> weeks = weeksInMonth(year, month);
        System.out.printf("weeks for %d/%d: [%s]\n", year, month, weeks);
        LinkedHashMap<Integer, Integer> whist = new LinkedHashMap<Integer, Integer>();
        LocalDate d1 = new LocalDate(year, month, 1);
        LocalDate d2 = d1.plusMonths(1);
        for( LocalDate d = d1; d.isBefore(d2); d = d.plusDays(1) ) {
            int wd = d.getWeekOfWeekyear();
            if( !whist.containsKey(wd) ) whist.put(wd, 0);
            whist.put(wd, whist.get(wd) + 1);
        }
        List<Integer> weeks2 = new ArrayList<Integer>();
        for( Integer wd : whist.keySet() ) {
            if( printdetail ) System.out.printf(" ( %d: %d) ", wd, whist.get(wd));
            if( whist.get(wd) >= 4 ) weeks2.add(wd);
        }
        if( printdetail ) System.out.println("");
        if( !weeks.equals(weeks2) ) { throw new RuntimeException("bad values"); }

    }

    public static void main(String[] args) {
        LocalDate d = new LocalDate(2010, 1, 1);
        for( int i = 0; i < 60; i++ ) {
            testWeeksInMonth(d.getYear(), d.getMonthOfYear(), true);
            d = d.plusMonths(1);
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM