Home > Blockchain >  Is there a way to categorize days and month into if statement?
Is there a way to categorize days and month into if statement?

Time:10-04

Rules for the seasons in the Northern Hemisphere

enter image description here

I am not sure how to add 01,02,03,04 months as winters and rest as their respective seasons. I am aware that we have to use if statements, but I want to know if we can categorize them.

CodePudding user response:

To add an answer to @user9596600

This looks like a case for switch statements! (Yes I have read the exercise but I still think this is good to know) If you don't know what they are here is a great example with mapping a number to a month. This uses the "old" switch expression. But since java 12 you are able to use this new syntax which looks a lot cleaner

We will proceed just as written in the exercise. First figure out the month and set the season accordingly after which we will calculate if the day has passed into the next season.

Part 1:

I'll just assume your method declaration is
private String getSeason(int month, int day)
and that season will be the variable to return.
An example switch statement could look as followed

switch (month) {
    case 1, 2, 3 -> season = "Winter";
    case 4, 5, 6 -> season = "Spring";
    case 7, 8, 9 -> season = "Summer";
    case 10, 11, 12 -> season = "Fall";
    default -> season = "No season at all >:(";
}

As you saw, you can "categorize" months into their appropriate season. Now onto

Part 2:

You are also able to use switch statements on String objects. To do that

if (month % 3 == 0 && day >= 21) {
    switch (season) {
        case "Winter" -> season = "Spring";
        case "Spring" -> season = "Summer";
        case "Summer" -> season = "Fall";
        case "Fall" -> season = "Winter";
    }
}

So in the end you'd have a clean and neat solution looking something like this

private String getSeason(int month, int day) {
    String season;

    switch (month) {
        case 1, 2, 3 -> season = "Winter";
        case 4, 5, 6 -> season = "Spring";
        case 7, 8, 9 -> season = "Summer";
        case 10, 11, 12 -> season = "Fall";
        default -> season = "No season at all >:(";
    }

    if (month % 3 == 0 && day >= 21) {
        switch (season) {
            case "Winter" -> season = "Spring";
            case "Spring" -> season = "Summer";
            case "Summer" -> season = "Fall";
            case "Fall" -> season = "Winter";
        }
    }

    return season;
}

CodePudding user response:

Since seasons are a bit shifted here, an array of strings could be used and seasonId should be calculated according to the mentioned rules:

public static String[] seasons = {"Winter", "Spring", "Summer", "Fall"};

public static String getSeason(int month, int day) {
    int seasonId = (month - 1) / 3 % seasons.length;

    if (day >= 21 && month % 3 == 0) {
        seasonId = (seasonId   1) % seasons.length;
    }
    return seasons[seasonId];
}

Test:

System.out.println(" 3/23 -> "   getSeason(3, 23));
System.out.println(" 6/01 -> "   getSeason(6, 1));
System.out.println(" 6/28 -> "   getSeason(6, 28));
System.out.println(" 9/21 -> "   getSeason(9, 21));
System.out.println("12/20 -> "   getSeason(12, 20));
System.out.println("12/25 -> "   getSeason(12, 25));

Output:

 3/23 -> Spring
 6/01 -> Spring
 6/28 -> Summer
 9/21 -> Fall
12/20 -> Fall
12/25 -> Winter

Following comment by @user16320675, a version with Java 12 switch statement may look like this:

public static String getSeason(int month, int day) {
    return switch(month) {
        case 1, 2 -> "Winter";
        case 3 -> day < 21 ? "Winter" : "Spring";
        case 4, 5 -> "Spring";
        case 6 -> day < 21 ? "Spring" : "Summer";
        case 7, 8 -> "Summer";
        case 9 -> day < 21 ? "Summer" : "Fall";
        case 10, 11 -> "Fall";
        case 12 -> day < 21 ? "Fall" : "Winter";
        default -> "Season undefined for bad month: "   month;
    }
}

CodePudding user response:

You don't need any if or switch at all. Actually it is easier by doing some integer division and modulo.

public static String[] seasons = {"Winter", "Spring", "Summer", "Fall"};

public static String getSeason(int month, int day) {
    int d = 30 * month   day - 21;  // days since winter begin
    int seasonId = d / 90 % 4;
    return seasons[seasonId];
}

Test:

System.out.println(" 3/20 -> "   getSeason(3, 20));
System.out.println(" 3/21 -> "   getSeason(3, 21));
System.out.println(" 6/20 -> "   getSeason(6, 20));
System.out.println(" 6/21 -> "   getSeason(6, 21));
System.out.println(" 9/20 -> "   getSeason(9, 20));
System.out.println(" 9/21 -> "   getSeason(9, 21));
System.out.println("12/20 -> "   getSeason(12, 20));
System.out.println("12/21 -> "   getSeason(12, 21));

Output:

 3/20 -> Winter
 3/21 -> Spring
 6/20 -> Spring
 6/21 -> Summer
 9/20 -> Summer
 9/21 -> Fall
12/20 -> Fall
12/21 -> Winter

CodePudding user response:

I think what you're trying to do is something like this:

if (1 <= month && month <= 3) { season = "Winter"; }
else if (4 <= month && month <= 6) { season = "Spring"; }
else if (7 <= month && month <= 9) { season = "Summer"; }
else if (10 <= month && month <= 12) { season = "Fall"; }
else { throw new RuntimeException("unexpected month"); }

if (month % 3 == 0 && day >= 21) {
    if (season.equals("Winter") { season = "Spring"; }
    else if (season.equals("Spring") { season = "Summer"; }
    else if (season.equals("Summer") { season = "Fall"; }
    else { season = "Winter"; }
}

What do you mean by categorizing IF statements? You could nest them like this:

if (1 <= month && month <= 3) { 
   if (month % 3 == 0 && day >= 21) {
       season = 'Winter';
   } else {
       season = 'Spring';
   }
else if (4 <= month && month <= 6) {
   if (month % 3 == 0 && day >= 21) {
       season = 'Summer';
   } else {
       season = 'Spring';
   }
} 
// etc ...
  • Related