views:

650

answers:

14

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.

+6  A: 

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
+1 for the second option
Skip Head
+10  A: 

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
I'd recommend http://joda-time.sourceforge.net ...
Dave Jarvis
+1 for the golfed solution. :-P
Chris Jester-Young
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
A: 

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
"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
edited to convoluted example[ruby] in place of list comprehension
dagoof
A: 

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
+2  A: 

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.

blackanchorage
28 on regular years 29 on leap
daddycardona
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
+1 for not reinventing the wheel.
Thanatos
Can you explain more on what you talking about blackanchorage
daddycardona
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
+5  A: 

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
they only contain 30 days and february conatains 28 regular and 29 on leap the rest of the months contain 31 days
daddycardona
It's difficult to tell that from the code.
Tom Hawtin - tackline
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
daddycardona
This doesn't return boolean. Add `> -1` to end.
BalusC
BalusC: Spotted.
Tom Hawtin - tackline
+19  A: 
if( 0x0A50 & (1<<month) != 0 )

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

irreputable
that would have been exactly my answer to the question..
Nils Pipenbrinck
+1 for the golfed solution. :-)
Chris Jester-Young
Perfect - waited for something like that - you made my day :)
schnaader
Four magic numbers in one line?
blackanchorage
+2  A: 

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
Bad code - no leap year logic. Feb has 29 days in leap years, so your code will be wrong.
duffymo
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
A: 

(moved into question)

daddycardona
I copied this info to the question, so people reading it will have the full problem description.
Jeff Meatball Yang
+3  A: 

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
Can you explain with a source code to help me understand?
daddycardona
**CAUTION**: java.util.Calendar use zero-based month constants, that is, `JANUARY == 0` and not 1 as usual !!!
Carlos Heuberger
That's exactly why I'm using the Calendar month constants. My code takes that into account. No caution needed.
duffymo
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
+3  A: 

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
Heh! That's longer than `(month == 4 || month == 6 || month == 9 || month == 11)`...
Jason Orendorff
+1  A: 

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

brianegge
A: 

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();
}
bibix
A: 

In Icon, you can do

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

You can also do

if a < b < c then ...

See also

polygenelubricants