Java日历在将月份的第一周定义为发生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 向前添加,而不是向后滚动 从星期天开始,而不是星期一 代码如下所示

我已经做了一个函数,可以得到给定月份的周数。对于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

  • 向前添加,而不是向后滚动

  • 从星期天开始,而不是星期一

代码如下所示:

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年的结果如下:

  • 一月五日
  • 二月四日
  • 三月四日
  • 四月四日
  • 五月五日
  • 六月四日
  • 七月五日
  • 八月四日
  • 九月四日
  • 十月五日
  • 十一月四日
  • 十二月四日

你认为三月有几周?把31天塞进4个星期有点难。还要注意的是,你在5月份展示了6个星期。。。第17周至第22周(含第17周至第22周)。您的代码显示的是“从x月开始的周”,因此第5周是正确的。@T.J.Crowder 2016年3月1日是:29 febr。-3月6日,3月2日:7-13日,3月3日:14-20日,上周:3月21-27日。基本上,你的
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;
}