Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding day of the year

Tags:

java

I'm trying to find the day of the year after you enter a date. I have a way that works but it is not the best way it seems.

I ask for the date using a Scanner object then send it through to a method where it checks what day of the year it is.

public static int theDay(int month, int day, int year)
{
    int numDay = day;

    /* Code here to check for leap year */

    for(int i = 1; i < month; i++)
    {
        switch(i)
        {
           case 1:
             numDay += 31;
             break;
           case 2:
             numDay += 28;
             break;
           case 3:
             numDay += 31;
             break;
           ...
           ... //goes until case 12
           ...
        }
    }

    return numDay;
}

I cannot use Calendar, LocalDate, arrays, and anything my teacher hasn't taught us yet. So just loops would be OK, I believe. As mentioned, this works and I get the correct day. But what would be a better way of doing this? Any help would be appreciated. Thanks!

like image 712
o.o Avatar asked Dec 25 '22 10:12

o.o


1 Answers

Depending on what you're using:

Standard Java libraries, before Java 8

Calendar calendar = new GregorianCalendar();
// Just to avoid corner cases
calendar.setTimeZone(TimeZone.getTimeZone("Etc/UTC"));
calendar.set(year, month - 1, day);
int dayOfYear = calendar.get(Calendar.DAY_OF_YEAR);

Joda Time

LocalDate date = new LocalDate(year, month, day);
int dayOfYear = date.getDayOfYear();

Java 8, using java.time

LocalDate date = LocalDate.of(year, month, day);
int dayOfYear = date.getDayOfYear();

Coding it yourself

(Now that we know that's what you need to do.)

Your current approach is okay, if you really need to do this yourself. You can do it without a loop though:

int daysInFebruary = ...; // Leap year calculation

switch (month)
{
    case 1:
        break; // Nothing to do
    case 2:
        numDay += 31; // Just add January
        break;
    case 3:
        numDay += 31 + daysInFebruary; // Add January and February
        break;
    case 4:
        numDay += 31 + daysInFebruary + 31; // Add January to March
        break;
    case 5:
        numDay += 31 + daysInFebruary + 31 + 30; // Add January to April
        break;
    // etc
    default:
        throw new IllegalArgumentException("Invalid month: " + month);
}

That's more efficient, but I'd consider it less readable than the code you've already got.

It would be much cleaner to do this with an array, mind you - you could have one array with the lengths of each month, and another with the cumulative lengths of each month (0, 31, 59 etc). Add a special case for leap years, and Bob's your uncle. But if you're not allowed to use arrays...

like image 152
Jon Skeet Avatar answered Jan 02 '23 09:01

Jon Skeet