Java Calendar的setMonth方法是否有效?

时间:2015-07-04 10:11:29

标签: java calendar

我有一些小代码,如下所示。我希望结果应为7,但它会打印6。如果我取消注释行tmp.get(Calendar.MONTH),它会运行正常(打印7)。

请让我知道原因。我在MacOS中使用JDK 1.7.0_25。

public static void main(String[] args) {
    Calendar tmp = Calendar.getInstance();
    tmp.set(Calendar.DAY_OF_MONTH, 4);
    tmp.set(Calendar.MONTH, Calendar.AUGUST);
    //tmp.get(Calendar.MONTH);
    tmp.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
    System.out.println(tmp.get(Calendar.MONTH));
}

屏幕截图:
评论代码:http://gyazo.com/4c099b1b2b90d72d1954b98b134e4ac3
取消注释代码:http://gyazo.com/fe368745da168646140ca9f3a60d2021

5 个答案:

答案 0 :(得分:3)

因为月份索引从索引0开始,所以在获得月份时添加+1。它是基于c的结构复制到java中。它的索引为0到11。

我认为每个月的日期不正确。评论并运行它正确显示。(tmp.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);

    tmp.set(Calendar.DAY_OF_MONTH, 4);
    tmp.set(Calendar.MONTH, Calendar.AUGUST);
    //tmp.get(Calendar.MONTH);
    //tmp.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
    System.out.println(tmp.get(Calendar.MONTH));

默认情况下,2015年和8月4日需要一年tuesday而不是monday

答案 1 :(得分:2)

我试图运行你的代码并且每次打印7(甚至试图取消注释你提到的那条线)。这似乎对我来说是正确的。

编辑详细解释了问题Java Calendar - Date is unpredictable after setting day_of_week

我很高兴Java 8带来了用于处理日期和时间的新API。

<强> EDIT2

我对发生的事情的理解:

只有合理的组合

YEAR + MONTH + DATE (let's call it A)

YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK (let's call it B)

日历有其内在的约会状态,他认为他是。所以基本上在你设置之前

DAY_OF_WEEK

您正在使用组合A,但在此之后您正在使用组合B和此行

tmp.set(Calendar.DAY_OF_MONTH, 4);

被忽略了。因此,周一在8月的第一周(2015-07-27)。但是当你打电话时

tmp.get(Calendar.MONTH);

你&#34;具体化&#34;根据组合A的日期(所以到2015-08-04)和

DAY_OF_WEEK

正确设置&#34;&#34;从2015-08-04开始。

无论如何,您可以尝试使用JDK 8吗?

答案 2 :(得分:1)

当您设置DAY_OF_WEEK =星期一时,日历会返回上周一,也就是7月27日,您可以使用System.out.println(tmp.get(Calendar.DAY_OF_MONTH));

进行检查

答案 3 :(得分:0)

避免使用Java-8之前的日期和日历

  

The existing Java date and time classes are poor, mutable, and have unpredictable performance.

这在某种程度上同样适用于Calendar,它有一些相同的问题。 Weaknesses of Calendar(德语链接)

  • 不是真正的日历,而是日期+时间
  • 可变
  • 1月是0个月,而不是1 st
  • 不直观的API:您必须使用get(Calendar.HOUR)代替getHour
  • ...

如果您使用的是Java&lt; 8,请使用Joda-Time

java-calendar-date-is-unpredictable-after-setting-day-of-week的评论中,Joda-Time建议作为@JonSkeet的替代方案,JDK Enhancement Proposal的那些人。您的代码可能看起来像

import org.joda.time.MutableDateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public class Test2 {
    public static void main(String[] args) {
    MutableDateTime tmp = new MutableDateTime();
    tmp.setDayOfMonth(4);
    tmp.setMonthOfYear(8);
    tmp.setDayOfWeek(1);

    DateTimeFormatter fmt = DateTimeFormat.fullDate();
    System.out.println(fmt.print(tmp));
    }
}

不可变

还有immutable DateTime类,which you will want to use instead。 (不变性增加了几个积极的影响,在Java 8中它是the default

import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

public class Test {
    public static void main(String[] args) {
        DateTimeFormatter fmt = DateTimeFormat.fullDate();

        DateTime tmp = new DateTime().withDayOfMonth(4).withMonthOfYear(8);
        System.out.println(fmt.print(tmp));

        tmp = tmp.withDayOfWeek(1);
        System.out.println(fmt.print(tmp));
    }
}

如果在Java-8上,

java.time API基于Joda-Time。使用

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class Test {
    public static void main(String[] args) {
        DateTimeFormatter fmt = DateTimeFormatter.RFC_1123_DATE_TIME;

        LocalDateTime tmp
            = LocalDateTime.now().withDayOfMonth(4).withMonthOfYear(8);
        System.out.println(fmt.format(tmp));

        tmp = tmp.withDayOfWeek(1);
        System.out.println(fmt.format(tmp));
    }
}

(我还没有测试过Java-8版本)

答案 4 :(得分:0)

当您设置星期几时,日历无法知道您的期望。如果您希望获得同一周的另一天的日期,您应该设置一周中的一周来指示您期望的那一周。