Question

Is there an analogous form of the following code:

if(month == 4,6,9,11)
{
  do something;
}

Or must it be:

if(month == 4 || month == 6 etc...)
{
  do something;
}

I am trying to write an if statement that checks if this month has more than 31 days.

EDIT

I guess the real problem is I undersand some of what I am taught but every time I try to use the sun website about java it just confuses me. My question is if I get a month in from a user and a day and I put it into a MM/dd format and evaluate it then is there an easier way to check if the month and the day is valid and after I check it for being valid I can either print the MM/dd in the format that I have. If it is not valid Print a line that says Invalid month or day.

Was it helpful?

Solution

If you're using C or Java, you can do this:

switch (month) {
  case 4:
  case 6:
  case 9:
  case 11:
    do something;
    break;
}

In some languages, you could even write case 4,6,9,11:. Other possibilities would be to create an array [4,6,9,11], some functional languages should allow something like if month in [4,6,9,11] do something;

As Lior said, it depends on the language.

EDIT: By the way, you could also do this (just for fun, bad code because not readable):

if ((abs(month-5) == 1) || (abs(month-10) == 1)) do_something;

OTHER TIPS

if( 0x0A50 & (1<<month) != 0 )

dude, this is ridiculous. (month==4||month==6||month==9||month==11) is perfectly ok.

You don't specify the language, but if you're using Java then yes, you have do do it the second way, or otherwise use switch:

switch(month) {
  case 4:
  case 6:
  case 9:
  case 11:
    do something;
}

Alternatively, you might find it useful and cleaner (depending on the design) to not hard-code the values but keep them elsewhere:

private static final Collection<Integer> MONTHS_TO_RUN_REPORT = Arrays.asList(4, 6, 9, 11);
....
if (MONTHS_TO_RUN_REPORT.contains(month)) {
  do something;
}   

This month

System.out.println("This month has " + new GregorianCalendar().getActualMaximum(Calendar.DAY_OF_MONTH) + " days in it.");

if statement to check if there is 31 days on this month

if (31 == new GregorianCalendar().getActualMaximum(Calendar.DAY_OF_MONTH))
{
    System.out.println("31 days on this month");
}
else
{
    System.out.println("Not 31 days in this month");
}

Write number of days for all months

Calendar cal = new GregorianCalendar();
for (int i = 0; i < 12; i++)
{
    cal.set(2009, i, 1); //note that the month in Calendar goes from 0-11
    int humanMonthNumber = i + 1;
    int max = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
    System.out.println("The " + humanMonthNumber + ". month has " + max  + " days.");
}

output:

This month has 30 days in it.
Not 31 days in this month
The 1. month has 31 days.
The 2. month has 28 days.
The 3. month has 31 days.
The 4. month has 30 days.
The 5. month has 31 days.
The 6. month has 30 days.
The 7. month has 31 days.
The 8. month has 31 days.
The 9. month has 30 days.
The 10. month has 31 days.
The 11. month has 30 days.
The 12. month has 31 days.

A rather literal translation into Java would be:

if (Arrays.binarySearch(new int[] { 4, 6, 9, 11 }, month) >= 0) {

I don't know what is so special about 4, 6, 9 and 11. You are probably better off using an enum, together with EnumSet or perhaps a method on the enum. OTOH, perhaps JodaTime does something useful.

I think your code will be more self-documenting if you use the static constants built into Calendar (e.g., Calendar.JANUARY, etc.)

If you do this often - more than once - I'd recommend writing a method named has31Days() or isReportMonth() to do the check in one place.

UPDATE:

The important thing isn't the months that have 31 days - it's the business rule that tells you something about reports for those months.

I might write it like this (hope I got the months with 31 days right):

public class ReportEngine
{
    public boolean isReportRequired(int month)
    {
        if ((month < Calendar.JANUARY) || (month > Calendar.DECEMBER))
            throw new IllegalArgumentException("Invalid month: " + month);

        // Reports are required for months with 31 days.
        return ((month == Calendar.JANUARY) || 
                (month == Calendar.MARCH) || 
                (month == Calendar.MAY) ||
                (month == Calendar.JULY) || 
                (month == Calendar.AUGUST) || 
                (month == Calendar.OCTOBER) ||
                (month == Calendar.DECEMBER));
    }
}

If you're checking if a month has more than 31 days, the simplest way to write it would be (in Java):

 public static boolean hasMoreThan31Days(final int month) {
    return false;
   } 

Don't do any specific checks. Try and convert to a valid date - if it throws an exception, report invalid date. After all you also need to check for day greater than 28 (or is it 29?) if the month is February.

C# as I don't know Java:

int[] DaysInMonth = new int[] {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}

if (DaysInMonth[month] == 31) ...

Forget the fancy logic that many people are advocating--this way is much clearer and easier to debug.

However, to answer the question you actually asked in your message:

if (false) ...

as there are no months with MORE than 31 days!

Edit: Yes, I didn't address the leap year. That has to be handled separately. The question was whether the month had 31 days, though--something mine DOES answer. I could have done it with an array of bools but since the array needs to be there anyway why not put the lengths in?

For dates I use Joda Time mentioned earlier, but I understand if it's not applicable for you. If you just want it to look nice, you can first define a list with values that you're interested in and then check if your month is in that list:

// This should be a field in a class
// Make it immutable
public static final List<Integer> LONGEST_MONTHS = 
        Collections.immutableList(Arrays.asList(4,6,9,11));

// Somewhere in your code
if(LONGEST_MONTHS.contains(month)) {
    doSomething();
}

No question about dates and Java would be complete without mentioning Joda Time.

for(int i = DateTimeConstants.JANUARY; i <= DateTimeConstants.DECEMBER; i++) {
    LocalDate localDate = new LocalDate().withMonthOfYear(i);
    System.out.println("    " +localDate.toString("MMMM") + " - " + localDate.dayOfMonth().getMaximumValue());
}

January - 31
February - 29
March - 31
April - 30
May - 31
June - 30
July - 31
August - 31
September - 30
October - 31
November - 30
December - 31

Simpe Aux function (C#) that gives you the number of days of a given month:

    private int GetDaysInMonth(DateTime date)
    {
        return new DateTime(date.Year, date.Month, 1).AddMonths(1).AddDays(-1).Day;
    }

Hope it helps

For pretty much any you'll need to use the second option, but in most languages you can write something similar to

if [4,6,9,11].map{|day|==month}.inject(false){|all, elem| all|elem}
    do thing

or better yet

if month in [4,6,9,11]:
    do thing

Perhaps if you are using C# you can do this:

public static class Extensions 
{
 public static bool IsIn(this Int32 intVal, params Int32[] vals)
 {
   return vals.Any(i => i == intVal)
 }
}

int month = 4;
if (month.IsIn(4,6,9,11)) {
//do something
}

In Icon, you can do

if month = (4|6|9|11) then ...

You can also do

if a < b < c then ...

See also

Am I the only one to come up with

month_has_31days = month % 2 == month < 8

at least in C, can't check for java right now

A complete solution, also taking leap year into account.

private static int getDaysInMonth(LocalDateTime localDateTime) {

    int daysInMonth = 0;
    int year = localDateTime.getYear();
    int month = localDateTime.getMonth().getValue();

    switch (month) {
        case 1: case 3: case 5:
        case 7: case 8: case 10:
        case 12:
            daysInMonth = 31;
            break;
        case 4: case 6:
        case 9:case 11:
            daysInMonth = 30;
            break;
        case 2:
            if(((year % 4 == 0) && !(year % 100 == 0) || (year % 400 == 0))) {
                daysInMonth = 29;
            } else {
                daysInMonth = 28;
            }
            break;
        default: System.out.println("Invalid month");
            break;
    }

    return daysInMonth;
}

tl;dr

EnumSet.of( Month.JANUARY , Month.MARCH , Month.MAY , Month.JULY , Month.AUGUST , Month.OCTOBER , Month.DECEMBER )
       .contains( Month.from( LocalDate.now() ) )

java.time

The modern approach uses the java.time classes that supplant the troublesome old date-time classes.

The Month enum defines an object for each month of the year.

EnumSet<Month> thirtyOneDayMonths = EnumSet.noneOf( Month.class ) ;
for( Month month : Month.values() ) {
    if( month.maxLength() == 31 ) {
        thirtyOneDayMonths.add( month ) ;
    }
}

See if the current month is in that collection of months that have 31 days.

LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) ) ;
Month currentMonth = Month.from( today ) ;
if( thirtyOneDayMonths.contains( currentMonth ) ) {
    …
}

Or you could just interrogate today's date.

LocalDate.now( ZoneId.of( "Pacific/Auckland" ) )
         .lengthOfMonth()

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Move to first of next month and subtract a day.

Calendar  cal=Calendar.getInstance();
cal.add(Calendar.MONTH,1);
cal.set(Calendar.DAY_OF_MONTH,1);
cal.add(Calendar.DATE, -1);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top