Java日历在将月份的第一周定义为发生1的周时显示错误的周数
我已经做了一个函数,可以得到给定月份的周数。对于1月、5月、7月和10月,应返回5周。 但是,它在3月、6月和9月返回5。十一月。令人惊讶的是,总周数是正确的(52) 输出: 第4周的数量 月初是指有第一天的一周。e、 g: 5月25日至1日Java日历在将月份的第一周定义为发生1的周时显示错误的周数,java,calendar,gregorian-calendar,Java,Calendar,Gregorian Calendar,我已经做了一个函数,可以得到给定月份的周数。对于1月、5月、7月和10月,应返回5周。 但是,它在3月、6月和9月返回5。十一月。令人惊讶的是,总周数是正确的(52) 输出: 第4周的数量 月初是指有第一天的一周。e、 g: 5月25日至1日 5月2日至8日 5月9日至15日 5月16日至22日 5月23日至29日 5月的5周: 根据我的评论,我推断您想要计算一个月的周数,从该月的第一个月开始 您需要: 将月份的日期设置为1 向前添加,而不是向后滚动 从星期天开始,而不是星期一 代码如下所示
5月2日至8日
5月9日至15日
5月16日至22日
5月23日至29日 5月的5周:
根据我的评论,我推断您想要计算一个月的周数,从该月的第一个月开始 您需要:
- 将月份的日期设置为
1
- 向前添加,而不是向后滚动
- 从星期天开始,而不是星期一
public static int getNofWeeksWithFirstWeekStartingWhenFirstDayOfMonthOccurs(Calendar calendar) {
while (calendar.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY) {
calendar.roll(Calendar.DATE, true);
}
int currentMonth = calendar.get(Calendar.MONTH);
int nextMonth = (currentMonth + 1) % 12;
int prePreviousMonth = (currentMonth + 12 - 2) % 12;
int nofWeeks = 0;
do {
int month = calendar.get(Calendar.MONTH);
if (month == currentMonth) {
nofWeeks++;
} else {
break;
}
calendar.add(Calendar.WEEK_OF_YEAR, 1);
} while (true);
return nofWeeks;
}
public static void main(String[] args) {
int numWeeks;
int totalWeeks=0;
for (int i = 0; i < 12; i++) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, 2016);
calendar.set(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.MONTH, i);
numWeeks=getNofWeeksWithFirstWeekStartingWhenFirstDayOfMonthOccurs(calendar);
System.out.println("no of weeks " + numWeeks);
}
}
我觉得你应该:
- 每个月的第一天做运动
- 从中确定上个月“借用”的“额外”天数(例如,如果第1天是星期一,则为0;如果第1天是星期二,则为1等)
- 将其添加到正常月份的天数中
- 除以7(隐式截断为0)
java.util.Calendar
,它将类似于:
// Note: day-of-week runs from Sunday (1) to Saturday (7).
// Entry 0 here is not used. We could do this without an array lookup
// if desired, but it's whatever code you think is clearest.
private static final int[] EXTRA_DAYS = { 0, 6, 0, 1, 2, 3, 4, 5 };
// Note: 0-based month as per the rest of java.util.Calendar
public static int getWeekCount(int year, int month) {
Calendar calendar = new GregorianCalendar(year, month, 1);
int dayOfWeekOfStartOfMonth = calendar.get(Calendar.DAY_OF_WEEK);
int extraDays = EXTRA_DAYS[dayOfWeekOfStartOfMonth];
int regularDaysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
int effectiveDaysInMonth = regularDaysInMonth + extraDays;
return effectiveDaysInMonth / 7;
}
如果可能的话,我建议改用Joda-Time或java.Time
根据该代码,2016年的结果如下:
- 一月五日
- 二月四日
- 三月四日
- 四月四日
- 五月五日
- 六月四日
- 七月五日
- 八月四日
- 九月四日
- 十月五日
- 十一月四日
- 十二月四日
getNoOfWeeks
打算返回什么还不清楚。听起来你可能对你期望它做什么有一个非常具体的想法,但是你没有在帖子中包括这个。一旦你这样做了,帮助你就会容易得多。(除此之外,“有第一天的一周是新月份的第一周”只是周的一种可能定义,而不是正常的ISO定义。)添加:calendar.set(calendar.day_of_month,1);将false更改为true:calendar.roll(calendar.DATE,true);使它不再工作。你仍然使用上个月还是改为下个月?你能发布一个代码示例吗?我应该把“上个月”改成“下个月”?文本更改?不仅是名称,还包括赋值:int nextMonth=(currentMonth+1)%12代码>编辑了带有您的改进的问题。一月和七月现在是正确的,5周。但剩下的还是不行。
no of weeks 5
no of weeks 4
no of weeks 4
no of weeks 4
no of weeks 5
no of weeks 4
no of weeks 5
no of weeks 4
no of weeks 4
no of weeks 5
no of weeks 4
no of weeks 4
// Note: day-of-week runs from Sunday (1) to Saturday (7).
// Entry 0 here is not used. We could do this without an array lookup
// if desired, but it's whatever code you think is clearest.
private static final int[] EXTRA_DAYS = { 0, 6, 0, 1, 2, 3, 4, 5 };
// Note: 0-based month as per the rest of java.util.Calendar
public static int getWeekCount(int year, int month) {
Calendar calendar = new GregorianCalendar(year, month, 1);
int dayOfWeekOfStartOfMonth = calendar.get(Calendar.DAY_OF_WEEK);
int extraDays = EXTRA_DAYS[dayOfWeekOfStartOfMonth];
int regularDaysInMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
int effectiveDaysInMonth = regularDaysInMonth + extraDays;
return effectiveDaysInMonth / 7;
}