当前位置: 首页 > 知识库问答 >
问题:

日历返回一年中错误的一周

赫连棋
2023-03-14

我想在将一周的第一天设置为周日后,将2018年10月9日这一周作为一年中的42周。我仍然从下面的代码片段中得到41的输出

 Calendar c = Calendar.getInstance();
 c.setFirstDayOfWeek(Calendar.SUNDAY);
 System.out.println( c.get(Calendar.WEEK_OF_YEAR)  );

我错过了什么吗?

背景:我们一周的开始可能是可变的。我们的配置能够让用户决定一周的第一天。

共有1个答案

萧远
2023-03-14

抱歉,我太固执了。我仍然认为你应该把计算留给一个定制的WeekFields对象。如果我正确理解了你的评论,你想:

    final int daysPerWeek = DayOfWeek.values().length; // A wordy way of writing 7 :-)
    WeekFields customWeekFields = WeekFields.of(firstDayOfWeek, daysPerWeek);
    int customWeekNumber = date.get(customWeekFields.weekOfWeekBasedYear());

为了测试这是否与您已经在做的事情一致,我编写了以下方法:

static void printWeekNumber(DayOfWeek firstDayOfWeek, LocalDate date) {
    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("EEE uuuu-MM-dd", Locale.ENGLISH);
    final int daysPerWeek = DayOfWeek.values().length;

    // Week number according to your comment: “using the Temporal adjusters
    // I am getting the date on the last day of the week.
    // After that dividing the Day of the Year from the API by 7”
    DayOfWeek lastDayOfWeek = firstDayOfWeek.minus(1);
    int askersCommentWeekNumber = date
            .with(TemporalAdjusters.nextOrSame(lastDayOfWeek))
            .getDayOfYear()
                    / daysPerWeek;

    // My suggested way of calculating the same week number
    WeekFields customWeekFields = WeekFields.of(firstDayOfWeek, daysPerWeek);
    int customWeekNumber = date.get(customWeekFields.weekOfWeekBasedYear());

    System.out.format(Locale.ENGLISH, "Week begins on %-8s Date is %s. Week %2d or %2d, agree? %s%n", 
            firstDayOfWeek, date.format(dateFormatter), 
            askersCommentWeekNumber, customWeekNumber, 
            askersCommentWeekNumber == customWeekNumber);
}

为了便于手工检查计算结果,我选择了不同年份的1月份:

    printWeekNumber(DayOfWeek.SUNDAY, LocalDate.of(2017, Month.JANUARY, 9));
    printWeekNumber(DayOfWeek.MONDAY, LocalDate.of(2017, Month.JANUARY, 9));
    printWeekNumber(DayOfWeek.THURSDAY, LocalDate.of(2017, Month.JANUARY, 9));
    printWeekNumber(DayOfWeek.SUNDAY, LocalDate.of(2018, Month.JANUARY, 9));
    printWeekNumber(DayOfWeek.MONDAY, LocalDate.of(2018, Month.JANUARY, 9));
    printWeekNumber(DayOfWeek.SUNDAY, LocalDate.of(2019, Month.JANUARY, 9));
    printWeekNumber(DayOfWeek.MONDAY, LocalDate.of(2019, Month.JANUARY, 9));

输出:

Week begins on SUNDAY   Date is Mon 2017-01-09. Week  2 or  2, agree? true
Week begins on MONDAY   Date is Mon 2017-01-09. Week  2 or  2, agree? true
Week begins on THURSDAY Date is Mon 2017-01-09. Week  1 or  1, agree? true
Week begins on SUNDAY   Date is Tue 2018-01-09. Week  1 or  1, agree? true
Week begins on MONDAY   Date is Tue 2018-01-09. Week  2 or  2, agree? true
Week begins on SUNDAY   Date is Wed 2019-01-09. Week  1 or  1, agree? true
Week begins on MONDAY   Date is Wed 2019-01-09. Week  1 or  1, agree? true

不过,请检查结果是否符合您的要求。对于你问题中的例子,结果既不是41也不是42:

    printWeekNumber(DayOfWeek.SUNDAY, LocalDate.of(2018, Month.OCTOBER, 9));
Week begins on SUNDAY   Date is Tue 2018-10-09. Week 40 or 40, agree? true

编辑:如果您想要ISO 8601周数,请使用date.get(WeekFields. ISO. dayOfWeek())。如果您想要与ISO 8601相同的自定义一周的第一天和第一周的4天,请使用:

    WeekFields customWeekFields = WeekFields.of(firstDayOfWeek, 4);
 类似资料:
  • 我想创建一个日历对象,并将其设置为某一年和该年中的一周。 当我将calendar对象传递给setWeekChecked方法时,这是它的toString: java.util.gregoriancalendar[time=?,arefieldsset=false,lenient=true,zone=America/New_York,firstDayofWeek=1,minimalDaysinfirs

  • 问题内容: 执行以上代码段后,month的值为10而不是11。 问题答案: 月份从0而不是1索引,因此10是11月,而11是12月。

  • 我有一个验证方法,将两个输入作为开始日期和结束日期,并检查结束日期是否有效,即在开始日期之后。我使用Calendar方法获取两个日期的毫秒数并得到差值。如果差值为负值,则其无效的结束日期,即结束日期早于开始日期。结束日期的毫秒值应始终大于开始日期。但在某些情况下,在开始日期的情况下,getTimeInMillis()会提供更大的值。 这是我的代码: 输出为: 这里2015-01-31是开始日期,2

  • 问题内容: 例如: 版画1 乔达时间也是如此。 问题答案: Year of Year的定义是依赖的。 其他帖子中讨论了在美国如何定义。例如在德国(DIN 1355-1 / ISO 8601):一年的第一周*是新年中具有四天或以上的第一周。 *一周的第一天是星期一,一周的最后一天是星期日 JavaCalendar注重语言环境。例如: 印刷品: 添加 对于美国(我认为墨西哥也是如此),每年的1.星期是

  • 我正在尝试为我们的财务部门生成一些代码,他们需要一个字段,该字段将为他们提供一年中的当前一周,但以星期天为基础,这是一周的第一天。例如01-25-16(MM dd yyyy)将是第4周。然而,当我尝试使用和

  • 问题内容: 所以我在这里呆了几个小时,它返回正确的Year和Day,但是由于某种奇怪的原因,它返回了错误的月份。我确定它是一个简单的修复程序,但我似乎无法弄清楚。 问题答案: 要获得本月的1-12数字: 最好指定所需/预期的时区。 类似地,呼叫和。 细节 它返回错误的月份 就像其他人所说的,在 1月至12月的 几个月中,他们疯狂地编号为0-11, 而不是1-12。在旧的日期时间类中,许多糟糕的设计