【问题标题】:GregorianCalendar: Jumping from tuesday to sundayGregorianCalendar:从星期二跳到星期日
【发布时间】:2014-12-10 02:32:47
【问题描述】:

我有一个 9 月 2 日星期二的 GregorianCalendar 实例。该值以毫秒为单位进行检查并且正常。我想要另一个日历,即下周日(7 日)23:59:59。所以:

GregorianCalendar currentCalendar = MyClock.INSTANCE.getCurrentCalendar();
GregorianCalendar nextSunday =
    (GregorianCalendar)currentCalendar.clone();
// GregorianCalendar uses Sunday as first day of week, so we must
// advance one week
int currentWeek = nextSunday.get(GregorianCalendar.WEEK_OF_YEAR);
nextSunday.set(GregorianCalendar.WEEK_OF_YEAR,
    currentWeek + this.THIS_WEEK);
nextSunday.set(GregorianCalendar.DAY_OF_WEEK, GregorianCalendar.SUNDAY);
nextSunday.set(GregorianCalendar.HOUR_OF_DAY, 23);
nextSunday.set(GregorianCalendar.MINUTE, 59);
nextSunday.set(GregorianCalendar.SECOND, 59);
nextSunday.set(GregorianCalendar.MILLISECOND, 0);

因此,由于星期日是公历一周的第 1 天,而我在一年中的第 36 周,我添加一周,然后将日期设置为星期日。

现在真正的问题来了:当我在我的开发机器上执行时,使用 OpenJDK 1.7.0_55,它可以完美运行。如果我用 OpenJDK 1.7.0_51 去我的测试机器,它就全错了:

在 9 号星期二之前增加一周,然后转到 14 号星期日而不是 7 号星期日。

我不知道我这样做是对还是错:真正让我丧命的是结果取决于机器,而且我在 GregorianCalendar 上并没有发现这些 OpenJDK 版本有什么不同。对此行为有何解释?

PD:请坚持使用 GregorianCalendar。我知道这有点糟糕,但我不想在目前的开发阶段使用 Joda Calendar 或其他任何东西。

编辑:我找到了方法 setWeekDate(year, week_of_year, day_of_week)。有人会认为将年、周和星期几设置到相同的方法中会成功。它没有:仍然从第 2 位到第 14 位。这是什么猴子写的?

【问题讨论】:

  • 设置值后何时执行get?在Calendar 中设置值会将它们排成set,但在调用get 之前不会计算它们。
  • 仅供参考,Joda-Time 和 Calendar 类现在都被 Java 8 及更高版本中内置的 java.time 类所取代。另外,提示:搜索“半开”以了解使用第二天开始而不是确定一天的最后时刻的更好方法,例如:23:59:59。

标签: java calendar gregorian-calendar


【解决方案1】:

我对您的代码做了一些小改动:

SimpleDateFormat sdf = new SimpleDateFormat("dd MM yyyy - HH:mm:ss.SSSS Z");
GregorianCalendar currentCalendar = (GregorianCalendar) Calendar.getInstance();
currentCalendar.set(Calendar.DAY_OF_MONTH, 2);
System.out.println(sdf.format(currentCalendar.getTime()));
GregorianCalendar nextSunday = (GregorianCalendar) currentCalendar.clone();
// GregorianCalendar uses Sunday as first day of week, so we must
// advance one week
int currentWeek = nextSunday.get(GregorianCalendar.WEEK_OF_YEAR);
nextSunday.set(GregorianCalendar.WEEK_OF_YEAR, currentWeek + 1);
nextSunday.set(GregorianCalendar.DAY_OF_WEEK, GregorianCalendar.SUNDAY);
nextSunday.set(GregorianCalendar.HOUR_OF_DAY, 23);
nextSunday.set(GregorianCalendar.MINUTE, 59);
nextSunday.set(GregorianCalendar.SECOND, 59);
nextSunday.set(GregorianCalendar.MILLISECOND, 0);
System.out.println(sdf.format(nextSunday.getTime()));

这个输出:

02 12 2014 - 19:40:46.0250 +0200
07 12 2014 - 23:59:59.0000 +0200

这是正确的。不过,我有两点要指出:

  1. 检查 this.THIS_WEEK 的值。我已将它替换为值 1,它在我的机器上运行正常。
  2. 检查两台机器上的时区(在我的情况下为 GMT+2)。由于两台机器都使用相同的代码来初始化值并使用它们,因此应该不存在问题。但是,如果您在不同的机器上使用毫秒值(例如通过网络服务或其他方式公开值),您可能会遇到问题。

【讨论】:

    【解决方案2】:

    我会尝试改用 java.util.Calendar 方法 add(int field, int amount)。

    nextSunday.add(Calendar.DAY_OF_MONTH,5)。一行代码而不是三行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-05
      • 1970-01-01
      • 1970-01-01
      • 2018-06-12
      • 2014-02-23
      • 2019-04-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多