日历 returns 一年中的第几周错误
Calendar returns wrong Week of the year
我想在将一周的第一天设置为星期日后,将 2018 年 9 月 10 日这一天作为一年中的第 42 周。我仍然从下面的代码片段中得到 41 的输出
Calendar c = Calendar.getInstance();
c.setFirstDayOfWeek(Calendar.SUNDAY);
System.out.println( c.get(Calendar.WEEK_OF_YEAR) );
我是不是漏掉了什么?
背景:我们的一周开始时间是可变的。我们的配置可以让用户决定一周的第一天。
抱歉我太执着了。我仍然认为您应该将计算留给自定义 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);
}
为了方便手工核对计算结果,我在不同年份的一月份选了一个日期:
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())
。如果您想要自定义一周的第一天和第一周的 4 天,如 ISO 8601,请使用:
WeekFields customWeekFields = WeekFields.of(firstDayOfWeek, 4);
我想在将一周的第一天设置为星期日后,将 2018 年 9 月 10 日这一天作为一年中的第 42 周。我仍然从下面的代码片段中得到 41 的输出
Calendar c = Calendar.getInstance();
c.setFirstDayOfWeek(Calendar.SUNDAY);
System.out.println( c.get(Calendar.WEEK_OF_YEAR) );
我是不是漏掉了什么?
背景:我们的一周开始时间是可变的。我们的配置可以让用户决定一周的第一天。
抱歉我太执着了。我仍然认为您应该将计算留给自定义 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);
}
为了方便手工核对计算结果,我在不同年份的一月份选了一个日期:
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())
。如果您想要自定义一周的第一天和第一周的 4 天,如 ISO 8601,请使用:
WeekFields customWeekFields = WeekFields.of(firstDayOfWeek, 4);