8

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.

Jeff Meatball Yang
  • 37,839
  • 27
  • 91
  • 125
AlThePal78
  • 793
  • 2
  • 14
  • 25
  • 4
    That really depends on the language you're programming in. Which language are you using? – Lior Cohen Nov 27 '09 at 00:02
  • Btw, none of the languages I know support the first syntax anyways. There are other ways to do this without the ||'s. – Lior Cohen Nov 27 '09 at 00:03
  • Why do you need 30-day months? There's probably something in your language of choice that helps you with this. – martin clayton Nov 27 '09 at 00:04
  • usually you have to write it the second way. If your language supports writing it in the first way, it would probably look more like: if month in (4,6,9,11) ... You can do that in SQL – dan Nov 27 '09 at 00:04
  • Java I am stumped and I have to get two projects that takes everyone here like 20 minutes with mistakes and take me days with out. I have laser surgery on Monday and the second one is due Monday and I am stuck on the first one lol – AlThePal78 Nov 27 '09 at 00:05
  • 1
    @Ether some people have to take programming courses at some point in their degree, regardless of their major or whether or not they wish to be programmers. Please don't judge without being aware of the circumstances :-) – Lior Cohen Nov 27 '09 at 00:09
  • 13
    That is my case I am taking it for college and its part of my degree, I only been doing it for a two months I am old have four kids and all that extra to report, I am in the USMC so my life is busy. I am not that great at this you might not be great at English or basketball. – AlThePal78 Nov 27 '09 at 00:13
  • @Ether: how do you come to this conclusion? Simply because some expects programming languages to have similar shortcuts to natural language? You seem to be so fixed in your thinking about programming language that you can't imagine a language where `month == 4,6,9,11` is actually a valid expression meaning "month is any of 4, 6, 9 or 11". Developing such a language is left as an exercise for the reader ;-) – Joachim Sauer Nov 27 '09 at 00:28
  • http://joda-time.sourceforge.net – Dave Jarvis Nov 27 '09 at 00:41
  • AFIK - good old COBOL is the only language that supports: " IF DAY = 4 or 6 or 9 or 11 " Althought I am sure you can do something shorter and unreadable in LISP. And please just youve been condition to write out logical expressions in long hand there no need to jump on the guy for asking a question which seems obvious to a newcomer. BTW: there are very valid reasons for avoiding "shortcut" syntax in logical expresions - thye quickly become non-obvious: " IF DAY NOT = 1 or 2 or 3 or 5 or 7 or 8 or 10 or 12 " does not do the obvious! – James Anderson Nov 27 '09 at 01:25
  • 1
    In SQL you can write `month IN (4, 6, 9, 11)` (or something, it's been many years since I've needed to touch SQL in anger). – Tom Hawtin - tackline Nov 27 '09 at 01:46
  • daddycardona: I guarantee I'm worse at basketball than you are at programming. Take it easy :) – Jason Orendorff Dec 15 '09 at 03:18
  • Has anybody noticed that months 4, 6, 9 and 11 (April, June, September, November) all have **30** days, not **31**? –  Dec 30 '11 at 22:28

19 Answers19

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

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

irreputable
  • 44,725
  • 9
  • 65
  • 93
12

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;
schnaader
  • 49,103
  • 10
  • 104
  • 136
  • Hehe - Although real golf code would be `((abs(m-5)==1)||(abs(m-10)==1))?do_something;` - and I'm pretty sure you could optimize that further by somehow combining the abs return values. – schnaader Nov 27 '09 at 01:02
7

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;
}   
Cowan
  • 37,227
  • 11
  • 66
  • 65
7

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.
zneo
  • 588
  • 3
  • 10
5

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.

Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305
  • they only contain 30 days and february conatains 28 regular and 29 on leap the rest of the months contain 31 days – AlThePal78 Nov 27 '09 at 00:24
  • thanks for letting me know that I wish I was as good as you, shoot i wish i was so good that I didnt need anyone and could help instead but dammit I dont understand all of this – AlThePal78 Nov 27 '09 at 00:48
  • This doesn't return boolean. Add `> -1` to end. – BalusC Dec 15 '09 at 03:30
4

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));
    }
}
duffymo
  • 305,152
  • 44
  • 369
  • 561
  • **CAUTION**: java.util.Calendar use zero-based month constants, that is, `JANUARY == 0` and not 1 as usual !!! – user85421 Nov 27 '09 at 10:33
  • 1
    That's exactly why I'm using the Calendar month constants. My code takes that into account. No caution needed. – duffymo Nov 27 '09 at 12:32
  • 1
    I think that the point of @Carlos is that the **caller** would have to pass `0`, `2`, `4`, etc for January, March, May, etc. – Pascal Thivent May 09 '10 at 05:42
3

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;
   } 
RAY
  • 6,810
  • 6
  • 40
  • 67
2

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.

  • 28 on regular years 29 on leap – AlThePal78 Nov 27 '09 at 00:18
  • Do you have an isLeapYear function in java? I'm saying that you're solving the easiest problem by checking for date greater than 30 for September, April, June and November. – blackanchorage Nov 27 '09 at 00:22
  • Can you explain more on what you talking about blackanchorage – AlThePal78 Nov 27 '09 at 01:26
  • Not sure exactley what the requirement is, but you could something like: Calendar cal = new GregorianCalendar(); cal.setLenient(false); cal.set(2009, 11, 31); The last statement will throw an exception, because that month doesn't have 31 days. Note if you don't call setLenient, it won't throw an exception, and the calendar gets 1 Dec instead. – blackanchorage Nov 27 '09 at 10:07
2

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?

Loren Pechtel
  • 8,945
  • 3
  • 33
  • 45
  • 1
    Bad code - no leap year logic. Feb has 29 days in leap years, so your code will be wrong. – duffymo Nov 27 '09 at 02:25
  • I have actually written a calendar program with this very code in it (in Javascript). I of course handled leap year separately, but this does the job in a lot of cases. – Jeff B May 09 '10 at 05:19
2

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

1

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

outis
  • 75,655
  • 22
  • 151
  • 221
brianegge
  • 29,240
  • 13
  • 74
  • 99
1

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();
}
Bartosz Bierkowski
  • 2,782
  • 1
  • 19
  • 18
0

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

Adrian Panasiuk
  • 7,249
  • 5
  • 33
  • 54
0

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
dagoof
  • 1,137
  • 11
  • 14
  • "Most languages" don't have list comprehensions like that, so long as we're talking about mainstream. Some - e.g. Python - do. Many - e.g. C++, Java - don't. – Pavel Minaev Nov 27 '09 at 00:08
  • edited to convoluted example[ruby] in place of list comprehension – dagoof Nov 27 '09 at 00:36
0

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
}
Igor Zevaka
  • 74,528
  • 26
  • 112
  • 128
0

In Icon, you can do

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

You can also do

if a < b < c then ...

See also

polygenelubricants
  • 376,812
  • 128
  • 561
  • 623
0

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;
}
Emmanuel Osimosu
  • 5,625
  • 2
  • 38
  • 39
0

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.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
-1

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);