当前位置: 首页 > 面试题库 >

2月来自java.util.Calendar的奇怪行为

阙阳
2023-03-14
问题内容

我遇到了来自java.util.Calendar的奇怪行为:

import static org.junit.Assert.*;
import org.junit.Test;

import java.util.Calendar;

public class Tester1 {
    @Test
    public void test_monthOfDate() {
        assertEquals(1, monthOfDate(2013, 1, 30)); // OK
        assertEquals(1, monthOfDate(2013, 1, 31)); // OK

        // Start of February
        assertEquals(2, monthOfDate(2013, 2, 1));  // FAIL
        assertEquals(2, monthOfDate(2013, 2, 28)); // FAIL
        // to the end of it

        // and after that it is okay also
        assertEquals(3, monthOfDate(2013, 3, 1));  // OK
    }

    public int monthOfDate(int year, int month, int day) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month - 1);

        // just a simple get! but seems it is very important
        cal.get(Calendar.MONTH);
        //

        cal.set(Calendar.DAY_OF_MONTH, day);

        return cal.get(Calendar.MONTH) + 1;
    }
}

我想知道为什么会这样吗?


问题答案:

问题是您要从2013年1月30日开始使用日历。

然后,您将年份设置为2013年-这不是问题。

然后,您将月份设置为1(即2月)。您希望在这里发生什么?实际发生的情况是,它会记住需要将月份设置为1,而 不是
重新计算实际时间值。根据文档(Emphsis我的),

在您调用to时重新计算时间值:get


set(f,value)将日历字段f更改为value。另外,它设置一个内部成员变量以指示日历字段f已更改。尽管日历字段f立即更改,但是直到下一次调用get(),getTime(),getTimeInMillis(),add()或roll()时,才重新计算日历的时间值(以毫秒为单位)。因此,对set()的多次调用不会触发多个不必要的计算。作为使用set()更改日历字段的结果,其他日历字段也可能会更改,具体取决于日历字段,日历字段值和日历系统。
此外,在重新计算日历字段之后,get(f)不一定会返回通过调用set方法设置的值。 具体情况由具体的日历类确定。

当您尝试将“ 1月30日”更改为“ 2月30日”并强制进行计算时, 实际 发生的情况是您将在3月2日结束我的工作,但是在实现上可能会有所不同。

最好的解决方法是:

  • 使用Calendar.set(year, month, date)代替来避免此订购问题
  • 首先,将Joda Time用作更明智的API。


 类似资料:
  • 下面的代码是一个小示例,可以轻松重现问题。所以我有 String 类型的变量,它设置了默认值。我有3种方法: getter 塞特 将字符串转换为布尔值的方便方法 自省不会将getter作为readMethod返回,将setter作为WriteMethod返回。相反,它将isTest()方法作为readMethod返回。setter为空。 从文档中我了解到,如果类型是boolean,那么" is "

  • 我有以下代码来解析一个JSON文件: 要处理以下JSON文件: 如果我执行此代码,我将收到以下错误: 所以我开始一步一步地调试应用程序,看看part processing()中的哪个代码部分抛出了这个异常。令人惊讶的是,那里的所有代码都正常执行:没有抛出异常,也没有返回结果I except。 更让我惊讶的是,当我稍微改变第一种方法的代码时,它可以在不产生异常的情况下工作。 我不知道println方

  • 问题内容: 这是我所有表的结构和查询 (请关注 下面的 最后一个 查询)。正如您在小提琴中看到的那样,这是 当前输出: 没错,一切都很好。 现在,我还有一个名为“类别”的存在。每个帖子只能有一个类别。而且我也想为每个用户获得前两个类别。而这里是我的新的查询。正如您在结果中看到的,发生了一些重复: 看到?,。为什么这些是重复的?我只是增加了一个对,一模一样。但是它不能按预期工作,甚至会影响标签。 无

  • 问题内容: 我在GregorianCalendar类中遇到一个奇怪的行为,我想知道我是否真的做得不好。 仅当初始化日期的月份的实际Maximum大于我将日历设置为的月份时,才追加此值。 这是示例代码: 我知道问题是由于日历初始化日期是31天(可能是5月),与设置为2月(28天)的月份混淆了。修复很容易(只需在设置年和月之前将day_of_month设置为1),但是我想知道这确实是想要的行为。有什么

  • 问题内容: 我正在为一个问题而苦苦挣扎,我不明白为什么它不起作用。如何通过将变量传递并转换为? 为什么在顶部代码段中不起作用,但在行下方的底部代码段中起作用? 唯一的区别似乎是添加了一个额外的变量,该变量也被键入为? 问题答案: 该是一种原始类型,同时是一个普通的Java类。您不能在原始类型上调用方法。但是该方法在上可用,如javadoc中所示 有关这些原始类型的更多信息,请参见此处

  • 问题内容: 为什么的到哪里去了? 问题答案: 删除任何字符,并从字符串的开头和结尾。