Используйте Календарь, чтобы узнать количество дней в феврале

java calendar

464 просмотра

5 ответа

13 Репутация автора

Вопрос в том, чтобы получить номера дней февраля любого года. Мой код такой:

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 31stи Mar 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

Кто-нибудь знает в чем здесь разница?

Автор: Zhengshuai PENG Источник Размещён: 18.07.2016 08:02

Ответы (5)


0 плюса

4292 Репутация автора

Не то чтобы это точный ответ. Но некоторое время назад я написал быструю Java-программу, которая будет генерировать календарь практически на любой месяц и год. Пример полностью соответствует тому, что вы пытаетесь сделать. Вот код, работающий на TutorialsPoint: календарь на 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];
    }

}
Автор: durbnpoisn Размещён: 18.07.2016 08:10

2 плюса

788 Репутация автора

Именно так и должно быть. Разница между 1 марта и 31 января на один день больше, чем количество дней в феврале. В общем, разница между одними и теми же днями в двух последовательных месяцах - это количество дней в самом раннем из этих двух месяцев. Таким образом, разница между 1 марта и 1 февраля - это количество дней в феврале, а также разница между 10 марта и 10 февраля (и любым другим днем). Разница между 1 апреля и 1 марта всегда составляет 31 (количество дней в марте) и так далее.

Автор: Ruslan Batdalov Размещён: 18.07.2016 08:12

0 плюса

357 Репутация автора

Измените свой первый метод на что-то вроде этого.

 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-е число марта, где для правильного ответа вам следует начать с 1-го февраля до 1-го марта. Проблема с расчетом.

Автор: Dishant Anand Размещён: 18.07.2016 08:14

0 плюса

382 Репутация автора

На это можно легко ответить с помощью простой математики.

Если вы вычитаете 0 из 30, (30 - 0 =?) Вы получаете 30.
Если вы вычитаете 1 из 30, (30 - 1 =?) Вы получаете 29.

Притворяться 0 - 0 февраля (что эквивалентно 31 января)
Притворяться 30 - 30 февраля (что эквивалентно 1 марта в високосный год)

Поэтому с 1 марта по 31 января должно быть 30 дней.

Чтобы получить желаемое количество дней, вы должны вычесть 1 из 30, а не 0 из 30.

Притворяться 1 - 1 февраля
Притворяться 30 - 30 февраля (что эквивалентно 1 марта в високосный год)

Поэтому вам нужно будет вычесть 1 марта из 1 февраля, чтобы получить правильное количество дней в феврале.

Автор: Yidna Размещён: 18.07.2016 08:19

0 плюса

139916 Репутация автора

ТЛ; др

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

Избегайте старых классов даты и времени

В Вопросе и других ответах используются трудные старые унаследованные классы даты и времени, включенные в самые ранние версии Java. Теперь вытеснены классами java.time.

YearMonth

Среди классов java.time - YearMonthгод и месяц.

Обратите внимание, что в java.time месяцы имеют нормальную нумерацию, 1-12 для января-декабря (в отличие от сумасшедших 0-11 в старых классах даты-времени).

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

Или вы можете использовать удобный Monthenum.

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

Опросите количество дней в этом месяце по телефону lengthOfMonth.

int lengthOfMonth = ym.lengthOfMonth() ;

Вы можете спросить, является ли год этого года високосным , позвонив по телефону isLeapYear.

boolean isLeapYear = ym.isLeapYear();

О java.time

Java.time каркас встроен в Java 8 и более поздних версий. Эти классы вытеснять неприятные старые классы даты и времени , такие как java.util.Date, .Calendar, и java.text.SimpleDateFormat.

Проект Joda-Time , находящийся сейчас в режиме обслуживания , рекомендует перейти на java.time.

Чтобы узнать больше, смотрите Oracle Tutorial . И поиск переполнения стека для многих примеров и объяснений.

Большая часть функциональности java.time перенесена на Java 6 и 7 в ThreeTen-Backport и дополнительно адаптирована для Android в ThreeTenABP (см. Как использовать… ).

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Вы можете найти некоторые полезные классы здесь , такие как Interval, YearWeek, YearQuarterи многие другие.

Автор: Basil Bourque Размещён: 31.08.2016 01:43
Вопросы из категории :
32x32