58
30 days hath September,
   April, June and November,
 All the rest have 31,
   Excepting February alone
(And that has 28 days clear,
   With 29 in each leap year).

Can I obtain this info anagrammatically? (I don't mean the poem, of course)

Manuel Araoz
  • 15,962
  • 24
  • 71
  • 95

4 Answers4

103

If you have a DateTime object which represents a value in the month, then it's pretty straightforward. You get the dayOfMonth property from that DateTime object and get the maximum value of the property. Here is a sample function:

public static int daysOfMonth(int year, int month) {
  DateTime dateTime = new DateTime(year, month, 14, 12, 0, 0, 000);
  return dateTime.dayOfMonth().getMaximumValue();
}
Dani
  • 3,744
  • 4
  • 27
  • 35
Erick Robertson
  • 32,125
  • 13
  • 69
  • 98
  • This didn't work for me. getMaximumValue() returns 31 for November, which is of course not correct. – Chris Gerken Nov 18 '13 at 20:02
  • 10
    @ChrisGerken: Maybe your months are zero-indexed? For JODA, the month should be a value from 1-12. If you used 10 for November, JODA would see that as October and return 31. – Erick Robertson Dec 26 '13 at 19:18
  • 2
    Nearly all of my date related bugs are because JODA is not zero indexed. It is tough to remember! – Chad Bingham Oct 20 '15 at 03:17
4

Yes, although it's not as pretty as it might be:

import org.joda.time.*;
import org.joda.time.chrono.*;
import org.joda.time.field.*;

public class Test {
    public static void main(String[] args) {
        GregorianChronology calendar = GregorianChronology.getInstance();
        DateTimeField field = calendar.dayOfMonth();

        for (int i = 1; i < 12; i++) {
            LocalDate date = new LocalDate(2010, i, 1, calendar);
            System.out.println(field.getMaximumValue(date));
        }
    }
}

Note that I've hard-coded the assumption that there are 12 months, and that we're interested in 2010. I've explicitly selected the Gregorian chronology though - in other chronologies you'd get different answers, of course. (And the "12 month" loop wouldn't be a valid assumption either...)

I've gone for a LocalDate rather than a DateTime in order to fetch the value, to emphasize (however faintly :) that the value doesn't depend on the time zone.

This is still not as simple as it looks, mind you. I don't know off-hand what happens if use one chronology to construct the LocalDate, but ask for the maximum value of a field in a different chronology. I have some ideas about what might happen, knowing a certain amount about Joda Time, but it's probably not a good idea :)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
0
Calendar cal = Calendar.getInstance();
cal.set(Calendar.MONTH, yourMonth);
cal.set(Calendar.YEAR, yourYear);
cal.getActualMaximum(Calendar.DAY_OF_MONTH); // <-- the result!
Benoit Courtine
  • 7,014
  • 31
  • 42
  • 2
    That's not Jodatime. The OP explicitly asked for this. – BalusC Sep 22 '10 at 19:46
  • Oups. Exact... I focused on the problem and forgot the title... But if the result can be obtained easily with the standard API, an external API like JodaTime is useless. – Benoit Courtine Sep 22 '10 at 20:03
  • 7
    I would personally stay *well* away from java.util.Calendar. Joda Time is a far, far superior API. For example, how confident are you about what that will do if you set it to February when `getInstance` returns the 31st of September? Oh, and don't forget that February is month 1... – Jon Skeet Sep 22 '10 at 20:20
  • I hear you about external API's, but Java's Calendar package is a known liability. Joda slides right in with no problems. – Erick Robertson Mar 15 '11 at 11:25
-1

Here is another simple function:

int daysOfMonth(DateTime dt) {
    int month = dt.getMonthOfYear();
    int month2 = month;
    int days = dt.getDay();
    DateTime dt2 = dt;
    while (month == month2 ) {
       days++;
       dt2.addDays(1);
       month2 = dt2.getMonthOfYear();
    }
    return (days - 1);
}
David.Chu.ca
  • 37,408
  • 63
  • 148
  • 190