例如:日期范围是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);
}
对不起,如果代码引起你的眼睛受伤,我知道这很糟糕:)
答案 0 :(得分: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);
}
答案 1 :(得分: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++;
}
}
}
总的来说。我鼓励你把你的逻辑分解成更小的更容易管理的方法。您不仅可以更轻松地重复使用此类代码,而且还可以降低其复杂性,从而使维护更加轻松。