Skip to main content
Notice removed Draw attention by Koray Tugay
Bounty Ended with forsvarir's answer chosen by Koray Tugay
Notice added Draw attention by Koray Tugay
Bounty Started worth 100 reputation by Koray Tugay
Tweeted twitter.com/StackCodeReview/status/785099575916892160
added 52 characters in body; edited title; edited tags
Source Link
200_success
  • 144.2k
  • 22
  • 188
  • 473

Removing code smells from day Day of year calculation method

public static int dayOfYear(int month, int dayOfMonth, int year) {
    if (month == 2) {
        dayOfMonth += 31;
    } else if (month == 3) {
        dayOfMonth += 59;
    } else if (month == 4) {
        dayOfMonth += 90;
    } else if (month == 5) {
        dayOfMonth += 31 + 28 + 31 + 30;
    } else if (month == 6) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31;
    } else if (month == 7) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30;
    } else if (month == 8) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31;
    } else if (month == 9) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31;
    } else if (month == 10) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30;
    } else if (month == 11) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31;
    } else if (month == 12) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 31;
    }
    return dayOfMonth;
}
public static int dayOfYear(int month, int dayOfMonth, int year) {
    if (month == 2) {
        dayOfMonth += 31;
    } else if (month == 3) {
        dayOfMonth += 59;
    } else if (month == 4) {
        dayOfMonth += 90;
    } else if (month == 5) {
        dayOfMonth += 31 + 28 + 31 + 30;
    } else if (month == 6) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31;
    } else if (month == 7) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30;
    } else if (month == 8) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31;
    } else if (month == 9) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31;
    } else if (month == 10) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30;
    } else if (month == 11) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31;
    } else if (month == 12) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 31;
    }
    return dayOfMonth;
}

Removing code smells from day of year calculation method

public static int dayOfYear(int month, int dayOfMonth, int year) {
    if (month == 2) {
        dayOfMonth += 31;
    } else if (month == 3) {
        dayOfMonth += 59;
    } else if (month == 4) {
        dayOfMonth += 90;
    } else if (month == 5) {
        dayOfMonth += 31 + 28 + 31 + 30;
    } else if (month == 6) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31;
    } else if (month == 7) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30;
    } else if (month == 8) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31;
    } else if (month == 9) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31;
    } else if (month == 10) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30;
    } else if (month == 11) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31;
    } else if (month == 12) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 31;
    }
    return dayOfMonth;
}

Day of year calculation method

public static int dayOfYear(int month, int dayOfMonth, int year) {
    if (month == 2) {
        dayOfMonth += 31;
    } else if (month == 3) {
        dayOfMonth += 59;
    } else if (month == 4) {
        dayOfMonth += 90;
    } else if (month == 5) {
        dayOfMonth += 31 + 28 + 31 + 30;
    } else if (month == 6) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31;
    } else if (month == 7) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30;
    } else if (month == 8) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31;
    } else if (month == 9) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31;
    } else if (month == 10) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30;
    } else if (month == 11) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31;
    } else if (month == 12) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 31;
    }
    return dayOfMonth;
}
added 53 characters in body
Source Link
Koray Tugay
  • 1.5k
  • 5
  • 20
  • 44

This looks like a trivial example but it took me some time to follow the 'best practices' such as immutable objects, SOLID principles, etc.. And I am not sure if I was successful in following them.

I advise you to give you a try yourself actually!

This looks like a trivial example but it took me some time to follow the 'best practices' such as immutable objects, SOLID principles, etc.. And I am not sure if I was successful in following them.

This looks like a trivial example but it took me some time to follow the 'best practices' such as immutable objects, SOLID principles, etc.. And I am not sure if I was successful in following them.

This looks like a trivial example but it took me some time to follow the 'best practices' such as immutable objects, SOLID principles, etc.. And I am not sure if I was successful in following them.

I advise you to give you a try yourself actually!

Source Link
Koray Tugay
  • 1.5k
  • 5
  • 20
  • 44

Removing code smells from day of year calculation method

The exercise I wanted to solve is from here. Copying from that page:

public static int dayOfYear(int month, int dayOfMonth, int year) {
    if (month == 2) {
        dayOfMonth += 31;
    } else if (month == 3) {
        dayOfMonth += 59;
    } else if (month == 4) {
        dayOfMonth += 90;
    } else if (month == 5) {
        dayOfMonth += 31 + 28 + 31 + 30;
    } else if (month == 6) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31;
    } else if (month == 7) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30;
    } else if (month == 8) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31;
    } else if (month == 9) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31;
    } else if (month == 10) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30;
    } else if (month == 11) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31;
    } else if (month == 12) {
        dayOfMonth += 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 31;
    }
    return dayOfMonth;
}

And I wanted to refactor this "smelly" example, and here is my implementation in Java.

Months are hardcoded with number of days they have:

public enum Month {

    JAN(1, 31, 31),
    FEB(2, 28, 29),
    MAR(3, 31, 31),
    APR(4, 30, 30),
    MAY(5, 31, 31),
    JUN(6, 30, 30),
    JUL(7, 31, 31),
    AUG(8, 31, 31),
    SEP(9, 30, 30),
    OCT(10, 31, 31),
    NOV(11, 30, 30),
    DEC(12, 31, 31);

    private final int monthIndex;
    private final int numberOfDaysInNonLeapYear;
    private final int numberOfDaysInLeapYear;

    Month(int monthIndex, int numberOfDaysInNonLeapYear, int numberOfDaysInLeapYear) {
        this.monthIndex = monthIndex;
        this.numberOfDaysInNonLeapYear = numberOfDaysInNonLeapYear;
        this.numberOfDaysInLeapYear = numberOfDaysInLeapYear;
    }

    public int getNumberOfDaysInNonLeapYear() {
        return numberOfDaysInNonLeapYear;
    }

    public int getNumberOfDaysInLeapYear() {
        return numberOfDaysInLeapYear;
    }

    public int getMonthIndex() {
        return monthIndex;
    }

    static Month getMonthForIndex(final int index) {
        final Month[] months = Month.values();
        for (final Month month : months) {
            if (month.monthIndex == index) {
                return month;
            }
        }
        return null;
    }
}

A Month has more meaning when it is a YearMonth:

public class YearMonth {

    private final Month month;
    private final boolean isLeapYear;
    private final int yearValue;

    public YearMonth(final int yearValue, final Month month) {
        this.yearValue = yearValue;
        this.month = month;
        if (yearValue % 4 == 0) {
            isLeapYear = true;
        } else {
            isLeapYear = false;
        }
    }

    public final int numberOfDays() {
        if (isLeapYear) {
            return month.getNumberOfDaysInLeapYear();
        }
        return month.getNumberOfDaysInNonLeapYear();
    }

    public final int dayOfYear(final int dayOfMonth) {
        int dayOfYear = 0;
        int monthIndex = month.getMonthIndex() - 1;

        while (monthIndex != 0) {
            final Month previousMonth = Month.getMonthForIndex(monthIndex);
            final YearMonth yearPreviousMonth = new YearMonth(yearValue, previousMonth);
            dayOfYear = dayOfYear + yearPreviousMonth.numberOfDays();
            monthIndex--;
        }

        return dayOfYear + dayOfMonth;
    }
}

Two sample test cases:

public class TestClass {
    public static void main(String[] args) {
        final Month january = Month.getMonthForIndex(1);
        final YearMonth january2016 = new YearMonth(2016, january);
        final int dayOfYearJanuary2016Day1 = january2016.dayOfYear(1);
        System.out.println("Day of Year 2016 for January Day 1: " + dayOfYearJanuary2016Day1);

        final Month march = Month.getMonthForIndex(3);
        final YearMonth march2014 = new YearMonth(2014, march);
        final int dayOfYearMarch2014Day2 = march2014.dayOfYear(2);
        System.out.println("Day of Year 2014 for March Day 2: " + dayOfYearMarch2014Day2);
    }
}

Output will be:

Day of Year 2016 for January Day 1: 1
Day of Year 2014 for March Day 2: 61

This looks like a trivial example but it took me some time to follow the 'best practices' such as immutable objects, SOLID principles, etc.. And I am not sure if I was successful in following them.

Any comments on code smells or fragility are welcome.