¿Número de días en un mes en particular de un año en particular?

158

¿Cómo saber cuántos días tiene un mes en particular de un año en particular?

String date = "2010-01-19";
String[] ymd = date.split("-");
int year = Integer.parseInt(ymd[0]);
int month = Integer.parseInt(ymd[1]);
int day = Integer.parseInt(ymd[2]);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR,year);
calendar.set(Calendar.MONTH,month);
int daysQty = calendar.getDaysNumber(); // Something like this
Klausos Klausos
fuente
77
¿Cuál es exactamente su pregunta?
ShaMan-H_Fel
Para su información, las antiguas clases de fecha y hora terriblemente problemáticas como java.util.Date, java.util.Calendary java.text.SimpleDateFormatahora son heredadas , suplantadas por las clases java.time integradas en Java 8 y posteriores. Ver Tutorial de Oracle .
Basil Bourque

Respuestas:

368

Java 8 y posterior

@Warren M. Nocos. Si está intentando usar la nueva API de fecha y hora de Java 8 , puede usar java.time.YearMonthclass. Vea el tutorial de Oracle .

// Get the number of days in that month
YearMonth yearMonthObject = YearMonth.of(1999, 2);
int daysInMonth = yearMonthObject.lengthOfMonth(); //28  

Prueba: prueba un mes en un año bisiesto:

yearMonthObject = YearMonth.of(2000, 2);
daysInMonth = yearMonthObject.lengthOfMonth(); //29 

Java 7 y versiones anteriores

Crea un calendario, establece año y mes y usa getActualMaximum

int iYear = 1999;
int iMonth = Calendar.FEBRUARY; // 1 (months begin with 0)
int iDay = 1;

// Create a calendar object and set year and month
Calendar mycal = new GregorianCalendar(iYear, iMonth, iDay);

// Get the number of days in that month
int daysInMonth = mycal.getActualMaximum(Calendar.DAY_OF_MONTH); // 28

Prueba : prueba un mes en un año bisiesto:

mycal = new GregorianCalendar(2000, Calendar.FEBRUARY, 1);
daysInMonth= mycal.getActualMaximum(Calendar.DAY_OF_MONTH);      // 29
Hemant Metalia
fuente
2
¿Cómo hacer esto en la nueva API de fecha y hora de Java 8?
Warren M. Nocos
2
@ WarrenM.Nocos lo siento por la respuesta tardía, pero no estuve activo estos meses. compruebe la edición de la solución para java 8.
Hemant Metalia
En cuanto a antes de Java 8 ... Gran parte de la funcionalidad java.time se transfiere a Java 6 y Java 7 en el proyecto ThreeTen-Backport . Más adaptado para Android anterior en el proyecto ThreeTenABP . Ver Cómo utilizar ThreeTenABP ... .
Basil Bourque
43

Código para java.util.Calendar

Si tiene que usar java.util.Calendar, sospecho que quiere:

int days = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);

Código para Joda Time

Personalmente, sin embargo, sugeriría usar Joda Time en lugar de java.util.{Calendar, Date}comenzar, en cuyo caso podría usar:

int days = chronology.dayOfMonth().getMaximumValue(date);

Tenga en cuenta que, en lugar de analizar los valores de cadena individualmente, sería mejor obtener cualquier API de fecha / hora que esté utilizando para analizarlo. En java.util.*usted puede usar SimpleDateFormat; en Joda Time usarías a DateTimeFormatter.

Jon Skeet
fuente
27

Puedes usar el Calendar.getActualMaximummétodo:

Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month);
int numDays = calendar.getActualMaximum(Calendar.DATE);
Aleks G
fuente
22

java.time.LocalDate

Desde Java 1.8, puede usar el método lengthOfMonthen java.time.LocalDate:

LocalDate date = LocalDate.of(2010, 1, 19);
int days = date.lengthOfMonth();
Alexandre DuBreuil
fuente
7
if (month == 4 || month == 6 || month == 9 || month == 11)

daysInMonth = 30;

else 

if (month == 2) 

daysInMonth = (leapYear) ? 29 : 28;

else 

daysInMonth = 31;
zoidbot
fuente
Calendario c = Calendar.getInstance (); c.set (Calendar.DAY_OF_MONTH, c.getActualMaximum (Calendar.DAY_OF_MONTH)); // puedes configurar el año antes de obtener el máximo real porque podrían no ser los mismos. es decir, febrero de 2011 y 2012 no es la misma duración (año bisiesto)
Rose
5

Esta es la forma matemática:

Por año, mes (1 a 12):

int daysInMonth = month == 2 ? 
    28 + (year % 4 == 0 ? 1:0) - (year % 100 == 0 ? (year % 400 == 0 ? 0 : 1) : 0) :
    31 - (month-1) % 7 % 2;
Shl
fuente
3

Yo buscaría una solución como esta:

int monthNr = getMonth();
final Month monthEnum = Month.of(monthNr);
int daysInMonth;
if (monthNr == 2) {
    int year = getYear();
    final boolean leapYear = IsoChronology.INSTANCE.isLeapYear(year);
    daysInMonth = monthEnum.length(leapYear);
} else {
    daysInMonth = monthEnum.maxLength();
}

Si el mes no es febrero (92% de los casos), depende solo del mes y es más eficiente no involucrar el año. De esta manera, no tiene que llamar a la lógica para saber si es un año bisiesto y no necesita obtener el año en el 92% de los casos. Y sigue siendo un código limpio y muy legible.

Stefan Mondelaers
fuente
1
Prefiero dejar toda la lógica a un método de biblioteca probado: creo que estás optimizando muy prematuramente, y los métodos de biblioteca no son tan ineficientes. Todavía votó por el uso del java.time moderno.
Ole VV
@ OleV.V. Es cierto que, en muchos casos, dejar la optimización en una biblioteca probada puede ser mejor. Pero, en este caso, las bibliotecas existentes deberán pasar un mes y un año. Eso significa que tengo que hacer lo que sea necesario para obtener el año de todos modos, incluso si el método no usará el valor en el 92% de los casos. Entonces, esa es una parte que no puede optimizar para mí. Mi razonamiento es similar al motivo por el que no debe hacer una llamada a un método para obtener un valor que se pasará a un registrador que podría estar deshabilitado. De ninguna manera el registrador puede optimizar eso.
Stefan Mondelaers
1

En Java8 puede usar get ValueRange de un campo de una fecha.

LocalDateTime dateTime = LocalDateTime.now();

ChronoField chronoField = ChronoField.MONTH_OF_YEAR;
long max = dateTime.range(chronoField).getMaximum();

Esto le permite parametrizar en el campo.

Jamie Lister
fuente
1

Tan simple como eso, no es necesario importar nada

public static int getMonthDays(int month, int year) {
    int daysInMonth ;
    if (month == 4 || month == 6 || month == 9 || month == 11) {
        daysInMonth = 30;
    }
    else {
        if (month == 2) {
            daysInMonth = (year % 4 == 0) ? 29 : 28;
        } else {
            daysInMonth = 31;
        }
    }
    return daysInMonth;
}
Ajay Chauhan
fuente
Esto está bien, si no necesita fechas históricas o fechas en un futuro lejano. Para febrero de años que son múltiplos de 100 pero no múltiplos de 400, será incorrecto. Pero estoy de acuerdo, en la mayoría de las aplicaciones esto servirá y es eficiente.
Stefan Mondelaers
1
// 1 means Sunday ,2 means Monday .... 7 means Saturday
//month starts with 0 (January)

MonthDisplayHelper monthDisplayHelper = new MonthDisplayHelper(2019,4);
int numbeOfDaysInMonth = monthDisplayHelper.getNumberOfDaysInMonth();
usuario11527435
fuente
1
Vale la pena señalar que es para Android ( android.util.MonthDisplayHelper)
barbsan
0
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/*
 * 44. Return the number of days in a month
 * , where month and year are given as input.
 */
public class ex44 {
    public static void dateReturn(int m,int y)
    {
        int m1=m;
        int y1=y;
        String str=" "+ m1+"-"+y1;
        System.out.println(str);
        SimpleDateFormat sd=new SimpleDateFormat("MM-yyyy");

        try {
            Date d=sd.parse(str);
            System.out.println(d);
            Calendar c=Calendar.getInstance();
            c.setTime(d);
            System.out.println(c.getActualMaximum(Calendar.DAY_OF_MONTH));
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
    public static void main(String[] args) {
dateReturn(2,2012);


    }

}
madhi vanan
fuente
1
¿Qué valor proporciona esta respuesta sobre las respuestas existentes y aceptadas? Además, agregue alguna explicación o narrativa junto con su código. StackOverflow es más que una biblioteca de fragmentos.
Basil Bourque
0
public class Main {

    private static LocalDate local=LocalDate.now();
    public static void main(String[] args) {

            int month=local.lengthOfMonth();
            System.out.println(month);

    }
}
Nodirbek Hasanboev
fuente
66
Agregue algunas explicaciones también.
BlackBeard
1
¡Bienvenido a Stack Overflow! Si bien este fragmento de código puede ser la solución, incluir una explicación realmente ayuda a mejorar la calidad de su publicación. Recuerde que está respondiendo la pregunta para los lectores en el futuro, y que esas personas podrían no conocer los motivos de su sugerencia de código.
yivi
0

El uso de obsoletos Calendar debe evitar el API .

En Java8 o una versión superior, esto se puede hacer con YearMonth .

Código de ejemplo:

int year = 2011;
int month = 2;
YearMonth yearMonth = YearMonth.of(year, month);
int lengthOfMonth = yearMonth.lengthOfMonth();
System.out.println(lengthOfMonth);
usuario6690200
fuente
Call requires API level 26 (current min is 21): java.time.YearMonth#lengthOfMonth
Vlad
0

Vamos a simplificarlo si no desea codificar el valor del año y el mes y desea tomar el valor de la fecha y hora actuales:

Date d = new Date();
String myDate = new SimpleDateFormat("dd/MM/yyyy").format(d);
int iDayFromDate = Integer.parseInt(myDate.substring(0, 2));
int iMonthFromDate = Integer.parseInt(myDate.substring(3, 5));
int iYearfromDate = Integer.parseInt(myDate.substring(6, 10));

YearMonth CurrentYear = YearMonth.of(iYearfromDate, iMonthFromDate);
int lengthOfCurrentMonth = CurrentYear.lengthOfMonth();
System.out.println("Total number of days in current month is " + lengthOfCurrentMonth );
RANA DINESH
fuente
0

Puede usar el método Calendar.getActualMaximum:

Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR, year);
calendar.set(Calendar.MONTH, month-1);
int numDays = calendar.getActualMaximum(Calendar.DATE);

Y el mes 1 es Debido a que el mes toma su número original de mes, mientras que en el método toma el argumento como se muestra a continuación en Calendar.class

public int getActualMaximum(int field) {
   throw new RuntimeException("Stub!");
}

Y el (campo int) es como a continuación.

public static final int JANUARY = 0;
public static final int NOVEMBER = 10;
public static final int DECEMBER = 11;
Dharmishtha
fuente
0

El siguiente método le proporcionará el número de días en un mes en particular

public static int getNoOfDaysInAMonth(String date) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    return (cal.getActualMaximum(Calendar.DATE));
}
Tanmay kumar shaw
fuente
0

Una variación óptima y eficaz:

public static int daysInMonth(int month, int year) {
    if (month != 2) {
        return 31 - (month - 1) % 7 % 2;
    }
    else {
        if ((year & 3) == 0 && ((year % 25) != 0 || (year & 15) == 0)) { // leap year
            return 29;
        } else {
            return 28;
        }
    }
}

Para obtener más detalles sobre el algoritmo de salto, consulte aquí

magiccrafter
fuente
-1
String  MonthOfName = "";
int number_Of_DaysInMonth = 0;

//year,month
numberOfMonth(2018,11); // calling this method to assign values to the variables MonthOfName and number_Of_DaysInMonth 

System.out.print("Number Of Days: "+number_Of_DaysInMonth+"   name of the month: "+  MonthOfName );

public void numberOfMonth(int year, int month) {
    switch (month) {
        case 1:
            MonthOfName = "January";
            number_Of_DaysInMonth = 31;
            break;
        case 2:
            MonthOfName = "February";
            if ((year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0))) {
                number_Of_DaysInMonth = 29;
            } else {
                number_Of_DaysInMonth = 28;
            }
            break;
        case 3:
            MonthOfName = "March";
            number_Of_DaysInMonth = 31;
            break;
        case 4:
            MonthOfName = "April";
            number_Of_DaysInMonth = 30;
            break;
        case 5:
            MonthOfName = "May";
            number_Of_DaysInMonth = 31;
            break;
        case 6:
            MonthOfName = "June";
            number_Of_DaysInMonth = 30;
            break;
        case 7:
            MonthOfName = "July";
            number_Of_DaysInMonth = 31;
            break;
        case 8:
            MonthOfName = "August";
            number_Of_DaysInMonth = 31;
            break;
        case 9:
            MonthOfName = "September";
            number_Of_DaysInMonth = 30;
            break;
        case 10:
            MonthOfName = "October";
            number_Of_DaysInMonth = 31;
            break;
        case 11:
            MonthOfName = "November";
            number_Of_DaysInMonth = 30;
            break;
        case 12:
            MonthOfName = "December";
            number_Of_DaysInMonth = 31;
    }
}
azhar
fuente
-1

Esto funcionó bien para mi.

Esta es una salida de muestra

import java.util.*;

public class DaysInMonth { 

    public static void main(String args []) { 

        Scanner input = new Scanner(System.in); 
        System.out.print("Enter a year:"); 

        int year = input.nextInt(); //Moved here to get input after the question is asked 

        System.out.print("Enter a month:"); 
        int month = input.nextInt(); //Moved here to get input after the question is asked 

        int days = 0; //changed so that it just initializes the variable to zero
        boolean isLeapYear = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); 

        switch (month) { 
            case 1: 
                days = 31; 
                break; 
            case 2: 
                if (isLeapYear) 
                    days = 29; 
                else 
                    days = 28; 
                break; 
            case 3: 
                days = 31; 
                break; 
            case 4: 
                days = 30; 
                break; 
            case 5: 
                days = 31; 
                break; 
            case 6: 
                days = 30; 
                break; 
            case 7: 
                days = 31; 
                break; 
            case 8: 
                days = 31; 
                break; 
            case 9: 
                days = 30; 
                break; 
            case 10: 
                days = 31; 
                break; 
            case 11: 
                days = 30; 
                break; 
            case 12: 
                days = 31; 
                break; 
            default: 
                String response = "Have a Look at what you've done and try again";
                System.out.println(response); 
                System.exit(0); 
        } 

        String response = "There are " + days + " Days in Month " + month + " of Year " + year + ".\n"; 
        System.out.println(response); // new line to show the result to the screen. 
    } 
} //[email protected]
Abhinav S Thakur
fuente
-1
String date = "11-02-2000";
String[] input = date.split("-");
int day = Integer.valueOf(input[0]);
int month = Integer.valueOf(input[1]);
int year = Integer.valueOf(input[2]);
Calendar cal=Calendar.getInstance();
cal.set(Calendar.YEAR,year);
cal.set(Calendar.MONTH,month-1);
cal.set(Calendar.DATE, day);
//since month number starts from 0 (i.e jan 0, feb 1), 
//we are subtracting original month by 1
int days = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
System.out.println(days);
Nagaraju Budigam
fuente
No es necesario responder a una pregunta que ya está aceptada, hasta que esa respuesta sea inválida.
Deepak