4

我想要一个函数,它在给定一周和一年的情况下返回下一周和一年。它看起来像:

public static int[] getNextWeek(int year, int week) {
    Calendar c = Calendar.getInstance(); // I'm Locale.US and TimeZone "America/New_York"
    c.clear();
    c.set(Calendar.YEAR, year);
    c.set(Calendar.WEEK_OF_YEAR, week);

    c.add(Calendar.WEEK_OF_YEAR, 1);

    return new int[] {c.get(Calendar.YEAR), c.get(Calendar.WEEK_OF_YEAR)}
}

这有时不适用于年份边界。这似乎取决于您调用它的日期以及您使用的参数!例如,如果我在 2012 年和第 52 周调用它,那么我希望结果是 2013 年和第 1 周。如果你今天调用它(2012 年 7 月 17 日星期二)它会起作用。如果您将星期几设置为昨天,则不会;并且在 2012 年第 1 周出现奇怪的结果。奇怪。到底是怎么回事?它似乎与星期几有关,因为如果用 SUNDAY 或 MONDAY(2012 年的最后两天)调用它就不起作用!如果我将星期几设置为一周的最后一天,该功能似乎可以工作;在调用 Calendar.add() 之前,我会:

    // Must set to last day of week; initially set to first day due to API
    c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek()); // SUNDAY
    c.add(Calendar.DAY_OF_WEEK, 6); // Must roll forward not backwards

如果我创建一个 getPreviousWeek 方法,似乎没有任何奇怪之处。这是 java.util.Calendar 错误吗?下次我想我会使用 Joda 时间!

4

3 回答 3

2

您是否考虑过 ISO8601 周算法认为一年中的第一周是该年至少有 4 天的这一事实?

因此,如果 1 月 1 日是星期四,那一周实际上被认为是上一年的第 52 周,而不是当年的第一周。

您可能至少要考虑 joda-time 进行这种计算,因为它可以正确处理 ISO 标准。

    LocalDate ld = new LocalDate();
    ld = ld.withWeekOfWeekyear(29);
    ld = ld.withWeekyear(2012);

    System.out.println(ld.getWeekOfWeekyear());
    System.out.println(ld.getWeekyear());

    // 29
    // 2012


    System.out.println(ld.plusWeeks(1).getWeekOfWeekyear());
    System.out.println(ld.plusWeeks(1).getWeekyear());
    // 30
    // 2012

这将跨越年份界限。

于 2012-07-18T02:49:43.250 回答
1

只需做一个明确的检查,看看是否有翻转。

return new int[] {c.get(Calendar.WEEK_OF_YEAR) == 1 ? c.get(Calendar.YEAR) + 1 :
    c.get(Calendar.YEAR), c.get(Calendar.WEEK_OF_YEAR)};

据我所知,WEEK_OF_YEAR没有正确添加的原因是因为它不是Calendarlike SECOND, MINUTE, MONTH, DAY, or的实际属性YEAR。它是一个派生属性,例如WEEK_OF_MONTH. 解决此问题的一种方法是使用c.add(Calendar.DAY, 7)恰好添加 7 天而不是递增WEEK_OF_YEAR.

于 2012-07-17T14:26:07.923 回答
1

在这一点上,我将假设这确实是一个错误。我在这里用 Oracle 填写了一个错误报告:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7197761

于 2012-09-19T18:59:33.840 回答