使用日历获取2月份的天数

时间:2016-07-18 20:02:53

标签: java calendar

问题是获取任何一年二月的日数。我的代码是这样的:

public static void main(String[] args) {
    System.out.println("2014-02 has " + getDaysOfFeb(2014) + "days");
    System.out.println("2016-02 has " + getDaysOfFeb(2016) + "days");
}

public static int getDaysOfFeb(int year) {
    Calendar c = Calendar.getInstance();
    // set year-01-31
    c.set(year, 0, 31);
    long lastDayofJan = c.getTimeInMillis();

    // set year-03-01
    c.set(year, 2, 1);
    long firstDayOfMar = c.getTimeInMillis();

    int date = (int) ((firstDayOfMar - lastDayofJan) / 1000 / 60 / 60 / 24);
}

我得到Jan 31stMar 1st,我用时间差来计算天数。但结果是:

2014-02 has 29days
2016-02 has 30days

我不明白为什么。

当我这样做时:

public static int getDaysOfFeb(int year) {
    Calendar c = Calendar.getInstance();
    // set year-01-31
    c.set(year, 2, 1);
    c.add(Calendar.DATE, -1); // last day of Feb
    int date = c.get(Calendar.DATE);
    return date;
}

结果是正确的,如下:

2014-02 has 28days
2016-02 has 29days

有谁知道这里的区别是什么?

5 个答案:

答案 0 :(得分:2)

应该是这样的。 3月1日和1月31日之间的差异比2月份的天数多一天。一般而言,连续两个月的同一天之间的差异是这两个月中最早的天数。因此,3月1日和2月1之间的差异是2月份的天数,以及3月10日和2月10日(以及任何其他日期)之间的差异。 4月1日和3月1之间的差异总是31(3月份的天数),依此类推。

答案 1 :(得分:0)

这不是一个确切的答案。但是我不久前写了一个快速的Java程序,它会为你想要的任何月/年创建一个日历。该示例与您尝试执行的操作直接相符。 这是在TutorialsPoint上运行的代码: Calendar in Java

代码:

import java.util.Calendar;

public class calDays {

    /**
     * @param args
     */
    static Calendar today = Calendar.getInstance();
    static int curDay = today.get(Calendar.DAY_OF_MONTH);
    static int curMonth = today.get(Calendar.MONTH);
    static int curYear = today.get(Calendar.YEAR);

    public static void main(String[] args) {

        drawCal(curMonth,curYear);
        drawCal(5,1969);
        drawCal(4,2001);
    }

    public static void drawCal(Integer monthIs, Integer yearIs){
        System.out.println(""+getMonth(monthIs)+" "+yearIs);
        System.out.println("S  M  T  W  T  F  S  ");

        int calDayBox =0;

        Calendar monthtd = Calendar.getInstance();
        monthtd.set(Calendar.DAY_OF_MONTH,1);
        monthtd.set(Calendar.MONTH, monthIs);
        monthtd.set(Calendar.YEAR, yearIs);

        int daysInMonth = monthtd.getActualMaximum(Calendar.DAY_OF_MONTH);

        int allboxes=0;
        //Draw leading days
        int CalDaxBoxVal=1;
        for (int xx=0;xx<monthtd.get(Calendar.DAY_OF_WEEK)-1;xx++){
            System.out.print("_  ");
            calDayBox++;
            allboxes++;
        }

        for (int xx=calDayBox;xx<daysInMonth+calDayBox;xx++){
            System.out.print(""+CalDaxBoxVal+ " ");
            if (CalDaxBoxVal<10) System.out.print(" ");
            CalDaxBoxVal++;
            allboxes++;
            if (allboxes%7==0) System.out.println(); 
        }

        System.out.println();
        System.out.println();



    }

    public static String getMonth(Integer whichMonth){
        String monthsAre[] = new String[12];
        monthsAre[0]="January";
        monthsAre[1]="February";
        monthsAre[2]="March";
        monthsAre[3]="April";
        monthsAre[4]="May";
        monthsAre[5]="June";
        monthsAre[6]="July";
        monthsAre[7]="August";
        monthsAre[8]="September";
        monthsAre[9]="October";
        monthsAre[10]="November";
        monthsAre[11]="December";

        return monthsAre[whichMonth];
    }

}

答案 2 :(得分:0)

将您的第一种方法改为这样的方法。

 Calendar c = Calendar.getInstance();  
 c.set(year, 1, 1);
 long firstDayOfFeb= c.getTimeInMillis();

 c.set(year, 2, 1);
 long firstDayOfMar = c.getTimeInMillis();

 int date = (int) ((firstDayOfMar - firstDayOfFeb) / 1000 / 60 / 60 / 24);
 return date;

在你的计算中,你实际上是从1月的最后一天到3月1日的计算,你应该从2月1日到3月1日开始正确答案。问题在于计算。

答案 3 :(得分:0)

这可以通过简单的数学来轻松回答。

如果你从30减去0,(30 - 0 =?)你得到30 如果你从30减去1,(30 - 1 =?)你得到29。

假装0是2月0日(相当于1月31日)
假装30是2月30日(相当于闰年3月1日)

因此,3月1日 - 1月31日必须是30天。

为了获得所需的天数,您必须从30减去1,而不是从30减去0.

假装1是2月1日 假装30是2月30日(相当于闰年3月1日)

因此,您需要从2月1日开始减去3月1日才能获得2月份的正确天数。

答案 4 :(得分:0)

TL;博士

YearMonth.parse( "2014-02" ).lengthOfMonth()

避免旧的日期时间类

问题和其他答案使用与最早版本的Java捆绑在一起的麻烦的旧遗留日期时间类。现在取代了java.time类。

YearMonth

在java.time类中,YearMonth代表一年和一个月。

请注意,在java.time中,月份的编号正确,1月至12月为1-12(与旧日期时间类中的疯狂0-11不同)。

YearMonth ym = YearMonth.parse( "2014-02" );

或者您可以使用方便的Month枚举。

YearMonth ym = YearMonth.of( 2014 , Month.FEBRUARY );

通过拨打lengthOfMonth来询问当月的天数。

int lengthOfMonth = ym.lengthOfMonth() ;

您可以致电Leap Year询问该年度的年份是isLeapYear

boolean isLeapYear = ym.isLeapYear();

关于java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧日期时间类,例如java.util.Date.Calendar和&amp; java.text.SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。

大部分java.time功能都被反向移植到Java 6&amp; ThreeTen-Backport中的7,并进一步适应Android中的ThreeTenABP(见How to use…)。

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuarter等。