0

例如:日期范围是从 2013 年 1 月 3 日到 2013 年 10 月 3 日。在上述范围内,获取每 3 个月第一周的所有工作日。结果将是这样的:

Thu Jan 03 00:00:00 ICT 2013
Fri Jan 04 00:00:00 ICT 2013
Sat Jan 05 00:00:00 ICT 2013
Sun Jan 06 00:00:00 ICT 2013
Mon Jan 07 00:00:00 ICT 2013
Mon Apr 01 00:00:00 ICT 2013
Tue Apr 02 00:00:00 ICT 2013
Wed Apr 03 00:00:00 ICT 2013
Thu Apr 04 00:00:00 ICT 2013
Fri Apr 05 00:00:00 ICT 2013
Sat Apr 06 00:00:00 ICT 2013
Sun Apr 07 00:00:00 ICT 2013
Mon Jul 01 00:00:00 ICT 2013
Tue Jul 02 00:00:00 ICT 2013
Wed Jul 03 00:00:00 ICT 2013
Thu Jul 04 00:00:00 ICT 2013
Fri Jul 05 00:00:00 ICT 2013
Sat Jul 06 00:00:00 ICT 2013
Sun Jul 07 00:00:00 ICT 2013
Tue Oct 01 00:00:00 ICT 2013
Wed Oct 02 00:00:00 ICT 2013

我已经想出了一种方法,但是代码看起来很丑,所以我想知道是否有任何方法会更优雅?谢谢你的帮助,我真的很感激。

// set up the startCal and endCal
String fmtShowTime = "ddMMyy"; // TODO: move to configurations
SimpleDateFormat sdf = new SimpleDateFormat(fmtShowTime);
TimeZone defaultZone = TimeZone.getDefault();
sdf.setTimeZone(defaultZone);
String fromTime = "030113";
String toTime = "031013";
Date startDate = sdf.parse(fromTime);
Date endDate = sdf.parse(toTime);
Calendar startCal = Calendar.getInstance();
startCal.setTime(startDate);
Calendar endCal = Calendar.getInstance();
endCal.setTime(endDate);

// set up the condition for week and month
Integer week = Integer.parseInt("1"); // first week
Integer monthPeriod = Integer.parseInt("3"); // every 3 months
Integer counter = 0;

while (startCal.getTimeInMillis() < endCal.getTimeInMillis()) {
    if (startCal.get(Calendar.DAY_OF_WEEK_IN_MONTH) == week) {
        // check if the current day in loop is the day of first week in month
        if (monthPeriod == 1)  {
            // get for every month
            for (int i = 0; i < 7; i++) {
                    if (startCal.get(Calendar.DAY_OF_WEEK_IN_MONTH) != week || startCal.getTimeInMillis() == endCal.getTimeInMillis()) {
                        // break for case like Tuesday, January 8th (2nd Tuesday of January) or October 4th (range breached) 
                        break;
                    }
                    System.out.println(startCal.getTime());
                    // move 1 more day
                    startCal.add(Calendar.DAY_OF_MONTH, 1);
            }
        }
        else {
            counter++;
            if (counter % monthPeriod == 1) {
                // I used counter mod monthPeriod to check if 3 months has passed in the loop, 1%3 = 1, 4%3 = 1 and so on
                for (int i = 0; i < 7; i++) {
                    if (startCal.get(Calendar.DAY_OF_WEEK_IN_MONTH) != week || startCal.getTimeInMillis() == endCal.getTimeInMillis()) {
                        // break for case like Tuesday, January 8th (2nd Tuesday of January) or October 4th (range breached)  
                        break;
                    }
                    System.out.println(startCal.getTime());
                    // move 1 more day
                    startCal.add(Calendar.DAY_OF_MONTH, 1);
                }
            } else {
                //if it's the first week of a month but not 3 months has passed yet then I forward 7 days to pass the check for first week of the month
                startCal.add(Calendar.DAY_OF_MONTH, 7);
            }
        }
    }
    startCal.add(Calendar.DAY_OF_MONTH, 1);
}

PS对不起,如果代码让你眼睛受伤,我知道这很糟糕:)

4

2 回答 2

0

查看我的解决方案

    GregorianCalendar c1 = new GregorianCalendar(2013, 0, 3);
    GregorianCalendar c2 = new GregorianCalendar(2013, 9, 3);
    while (c1.before(c2)) {
        if (c1.get(Calendar.WEEK_OF_MONTH) == 1 && c1.get(Calendar.MONTH) % 3 == 0) {
            System.out.println(c1.getTime());
        }
        c1.add(Calendar.DAY_OF_MONTH, 1);
    }
于 2013-01-15T12:07:09.363 回答
0

目前还不清楚是否应该包括周末。但是,根据我对您的要求的最佳猜测,我认为这是可行的:

public class DateIntervalDayParser {

    // Test harness
    public static void main(final String[] args) throws Exception {
        final int monthInterval = 3;
        final int daysFromStartOfMonth = 7;

        final DateIntervalDayParser parser = new DateIntervalDayParser();
        final List<Date> allWeekdays = parser.getWeekdays(
                new GregorianCalendar(2013, 0, 15), new GregorianCalendar(2013, 9, 15), monthInterval, daysFromStartOfMonth);

        for (final Date weekday : allWeekdays) {
            System.out.println(weekday);
        }
    }

    private List<Date> getWeekdays(final Calendar start, final Calendar end, final int monthInterval, int daysFromStartOfMonth)
    {
        // Start result list
        final List<Date> allWeekdays = new ArrayList<Date>();

        adjustStart(start, daysFromStartOfMonth);

        // Continue until start time has passed end time
        while (isMonthBeforeOrEqual(start, end)) {
            addWeekdays(allWeekdays, start, daysFromStartOfMonth);

            // Add month interval
            // NOTE: always set day of month to 1st day of month after 1st month
            start.set(Calendar.DAY_OF_MONTH, 1);
            start.add(Calendar.MONTH, monthInterval);

            // If we are in the last month, set last day of month maximum to last
            // months day if it is less than a week from the start of the month
            if (start.get(Calendar.YEAR) == end.get(Calendar.YEAR)
                    && start.get(Calendar.MONTH) == end.get(Calendar.MONTH)
                    && end.get(Calendar.DAY_OF_MONTH) < daysFromStartOfMonth) {
                daysFromStartOfMonth = end.get(Calendar.DAY_OF_MONTH);
            }
        }

        return allWeekdays;
    }

    private void adjustStart(final Calendar start, int daysFromStartOfMonth) {
        // If day of month in 1st month has passed max days from start of month,
        // start from the start of the next month
        if (start.get(Calendar.DAY_OF_MONTH) > daysFromStartOfMonth) {
            start.set(Calendar.DAY_OF_MONTH, 1);
            start.add(Calendar.MONTH, 1);
        }
    }

    private boolean isMonthBeforeOrEqual(final Calendar start, final Calendar end) {
        boolean beforeOrEqual = false;
        final int startYear = start.get(Calendar.YEAR);
        final int endYear = end.get(Calendar.YEAR);
        if (startYear < endYear) {
            beforeOrEqual = true;
        } else if (startYear == endYear) {
            beforeOrEqual = start.get(Calendar.MONTH) <= end.get(Calendar.MONTH);
        }
        return beforeOrEqual;
    }

    private void addWeekdays(final List<Date> days, final Calendar calendar, final int daysFromStartOfMonth) {
        // Add dates until day of month is exceeded
        int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
        while (dayOfMonth <= daysFromStartOfMonth) {
            days.add(calendar.getTime());

            // Increment
            calendar.add(Calendar.DAY_OF_MONTH, 1);
            dayOfMonth++;
        }
    }
}

在一般情况下。我鼓励你将你的逻辑分解成更小更易于管理的方法。您不仅可以更轻松地重用此类代码,而且还可以降低其复杂性,使维护更容易。

于 2013-01-15T12:32:04.883 回答