1

I made a program which converts days, months, and years into Julian days.

        int year, month, day;

            do
            {
                System.out.print("Enter the year ");
                year = keyIn.nextInt();
                    if(year < 1)
                    {
                        System.out.println("Invalid year entered!");
                        System.out.println(" ");
                    }
            }while(year < 1);
            do
            {
                System.out.print("Enter the month ");
                month = keyIn.nextInt();
                    if(month < 1 || month > 12)
                    {
                        System.out.println("Invalid month entered!");
                        System.out.println(" ");
                    }
            }while(month < 1 || month > 12);
            do
            {
                System.out.print("Enter the day ");
                day = keyIn.nextInt();
                    if(day < 1 ||day > 31)
                    {
                        System.out.println("Invalid day entered!");
                        System.out.println(" ");
                    }
            }while((month == 4 && day > 30) || (month == 2 && day > 29) || day < 1 ||day > 31);
                keyIn.close();              
                    int [] daysInAMonth = {31,28,31,30,31,30,31,31,30,31,30,31};

                        if(year % 4 == 0 && year % 100 != 0)
                        {
                            daysInAMonth[1] = 29;
                        }
                        else if(year%400==0 && year%100==0)
                        {
                            daysInAMonth[1] = 29;
                        }
                        else
                        {
                            daysInAMonth[1] = 28;
                        }
                            int julianDays = 0;
                                for (int i=0; i < month-1; i++)
                                {
                                    julianDays += daysInAMonth[i];
                                }
                                    julianDays += day;
                            System.out.println("The Julian Day is " +julianDays);  

But I have ran into some issues when a user enters dates such as 31th of March 2001 (2001, 4, 31), as there are only 30 days in April.
Is there a more efficient way to handle these errors rather than trying to test everything inside a do-while loop when user enters their date?

Mano
  • 125
  • 9
  • March has 31 days, actually, you can use April for your question.. – Massimo Petrus Nov 16 '16 at 09:26
  • Java's `Calendar` will actually tolerate days, months, etc. which are out of bound, and will try to roll over as best it can. I'm not saying this is necessarily the way to go, but if you don't want to deal with it, `Calendar` might make this possible. – Tim Biegeleisen Nov 16 '16 at 09:26
  • @Massimo I meant April, you are right, sorry. – Mano Nov 16 '16 at 09:28
  • One way to do it is to use a regex to control dates. I have one that control dates, with the possibility of february 29th. All you'd have to do is to concat your date as String first – DamCx Nov 16 '16 at 09:33
  • @Mano, no problem :) – Massimo Petrus Nov 16 '16 at 09:36

3 Answers3

2

I guess the main point of your code is learning how to do something like that. And for that purpose, it is ok.

Of course, if we would be talking "real world production" code, your code would not do:

  1. You avoid re-inventing the wheel for things that exist in standard libraries. And Java has actually several Date/Time APIs. (you would be looking at using the latest things added with Java8)
  2. You should avoid putting all this code into a single place. Instead; you could create helper methods.

Like:

private boolean isYearValid(int year) {
  return (year > 1);
}

and

private void boolean isMonthValid(...

but of course, to validate the day information you would need to pass month and year, too.

The point here is: validating dates is a complex undertaking. Thus you can't avoid putting down complex code that uses heavy if/else checking. But the point is: you should still try to make that code as readable as possible.

And many people think that having small methods with meaningful names, even simple things like:

boolean isLeapYear(int year)

will help you achieving that. So instead of cluttering your direct validation code with the code that checks if a year is leap year, you would be simply calling isLeapYear(year) instead. That doesn't make the complex checking itself go away, but you can move it outside of the context of your validation method!

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • Thank you for your answer, I will accept your answer as the material in my question is just prepping me for an exam and therefore I cannot use any other classes. – Mano Nov 16 '16 at 10:55
0

You may use java.util.Calendar, which can help on all this. For example create a Calendar, set year and month and use getActualMaximum.

    Calendar c=Calendar.getInstance();
    c.set(2012, 3, 1);
    System.out.println(c);
    System.out.println(c.getActualMaximum(Calendar.DAY_OF_MONTH));

Prints

Sun Apr 01 10:31:44 CEST 2012

30

The new java8 Date Time API has also some solutions, see Number of days in particular month of particular year?

Community
  • 1
  • 1
Massimo Petrus
  • 1,881
  • 2
  • 13
  • 26
  • 1
    I would absolutely not advise to go for Calendar. Why should a newbie learn about the deficient, old approach first. You better reverse order here: first tell about the new shiny reasonable Java8 APIs, then maybe mention that there is also that rusty dangerous Calendar stuff around. – GhostCat Nov 16 '16 at 09:39
-1

So you want the user to enter only numbers? In that case, put your whole code inside this:

try{
//code here
} catch(InputMismatchException ex) {
   System.out.println("Please enter numbers only.");
}

InputMismatchException checks if a value to be assigned to a variable is compatible with the data type of that variable.

Edit: Whoops. Sorry I thought you were asking an easier way to check if user input is a number. You could still use try and catch though.

ArcIX
  • 35
  • 4
  • how about to input 40?? OP want to get more efficient validation code instead of restricting to user. – Ye Win Nov 16 '16 at 09:33