最近我收到一封邮件,说 2012 年 12 月是一个特殊的月份。这个月有五个星期六、五个星期天和五个星期一。它还说这只会在大约 700 年中发生一次。所以,我需要检查在 2000 到 2100 之间分别有多少个月有五个星期六、星期日和星期一。
这可以通过java(特别是使用Calander API)来实现吗?
任何带有示例代码的想法都将是可观的。
谢谢。
最近我收到一封邮件,说 2012 年 12 月是一个特殊的月份。这个月有五个星期六、五个星期天和五个星期一。它还说这只会在大约 700 年中发生一次。所以,我需要检查在 2000 到 2100 之间分别有多少个月有五个星期六、星期日和星期一。
这可以通过java(特别是使用Calander API)来实现吗?
任何带有示例代码的想法都将是可观的。
谢谢。
对于任何一个月有 5 个(星期六、星期日、星期一),它必须:
java.util.Calendar
即使在根本上被破坏的API中,这两项检查也应该相当容易。(无论您有什么选择,都喜欢Joda Time。)如果您在实施其中一个时遇到困难,您应该发布一个特定的问题,向我们展示到目前为止您已经走了多远。
请检查以下代码:
/**
* Print all the months which has five Mondays, Saturdays and Sundays
* @param from year from
* @param to year to
*/
public void printMonths(int from, int to) {
List<String> monthList = new ArrayList<String>();
for (int year =from; year<=to;year++) {
monthList.addAll(getMonth(year));
}
for (String s : monthList) {
System.out.println(s);
}
}
/**
* Get month with five sundays, saturdays and mondays
* @param year
* @return
*/
private List<String> getMonth(int year) {
List<String> monthList = new ArrayList<String>();
for (int month = 0; month < 12; month++) {
if (check(year, month)) {
monthList.add("" + year + "-" + (month+1));
}
}
return monthList;
}
private boolean check(int year, int month) {
return checkFiveDays(year, month, 1) && checkFiveDays(year, month, 2)
&& checkFiveDays(year, month, 7);
}
private boolean checkFiveDays(int year, int month, int dayOfWeek) {
Calendar c = Calendar.getInstance();
c.set(year, month, 0, 0, 0, 0);
int times = 0;
do {
if (c.get(Calendar.DAY_OF_WEEK) == dayOfWeek) {
times++;
}
c.add(Calendar.DAY_OF_MONTH, 1);
} while (c.get(Calendar.MONTH)== month);
return times == 5;
}
实际上一个月有 5 个(星期六、星期日或星期一)没有必要有 31 天,请参阅 2012 年 9 月(即使是 2020 年等某些闰年的 2 月也可以有 5 个星期六)。甚至没有从那天开始的月份,请参阅:2013 年 3 月,周六案例。
使用 Joda 可以很容易地计算 2000 到 2100 之间的所有此类情况,例如:
DateTimeFormatter dateParser = DateTimeFormat.forPattern("yyyy");
DateTime startDate = dateParser.parseDateTime("2000");
DateTime stopDate = dateParser.parseDateTime("2100");
DateTime date = startDate;
DateTime lastInMonth;
if (date.getDayOfWeek() != DateTimeConstants.SATURDAY)
date = date.plusWeeks(1).withDayOfWeek(DateTimeConstants.SATURDAY);
int count = 0;
while (date.isBefore(stopDate)) {
if (date.getDayOfWeek() != DateTimeConstants.SATURDAY) //if it's not starting on Saturday
date = date.plusWeeks(1).withDayOfWeek(DateTimeConstants.SATURDAY); //jump to the first Saturday
lastInMonth = date.plusWeeks(4); //jump 4 weeks
if (date.getMonthOfYear() == lastInMonth.plusDays(2).getMonthOfYear()) { //check if we are still on the same month
count++;
// System.out.println("date = " + date); //uncomment to see each such month
}
date = date.plusMonths(1); //advance a month
date = date.withDayOfMonth(1); //start on the first day
}
System.out.println("Between " + startDate + " and " + stopDate + " there are " + count + " months that have five Saturdays");
once in some 700 years only
这并不完全正确,即使我们只计算 12 月份。