0

I'm planning to create a program in Java that determines if a year entered is a leap year and a valid date. Taking that date I want it to covert to a full written name (4/2/2013 = April 2nd, 2013) and then determine what that day number is in the year (4/2/2013 = Day 92).

There are a lot of programs that do one or another, but I'm learn ways/get ideas on how to combine it all in one if its possible.

To check the leap year, this is what i used:

public class LeapYear {
    public static void main (String[] args) {
    int theYear;
    System.out.print("Enter the year: ");
    theYear = Console.in.readInt();
    if (theYear < 100) {
        if (theYear > 40) {
        theYear = theYear + 1900;
        }
        else {
        theYear = theYear + 2000;
        }
    }
    if (theYear % 4 == 0) {
        if (theYear % 100 != 0) {
        System.out.println(theYear + " is a leap year.");
        }
        else if (theYear % 400 == 0) {
        System.out.println(theYear + " is a leap year.");
        }
        else {
        System.out.println(theYear + " is not a leap year.");
        }
    }
    else {
        System.out.println(theYear + " is not a leap year.");
    }
    }

}

I realize I need to change it a bit to also read the month and day of the year, but for this case, I'm just checking the year. How can I also take that same date entered and convert it to a full written name? Would I have to create an if statement like:

if (theMonth == 4){
     System.out.println("April");
         if (theDay == 2){
          System.out.print(" 2nd, " + theYear + ".");
         }
    }

That seems like a lot of hardcoded work. I'm trying limit the amount of hardcoding needed so I can get something like:

Output:
 Valid entry (4/2/2013).
 It is April 2nd, 2013.
 It is not a leap year.
 It is day 92.

If there is an error, like invalid date, I want the program to reprompt the user until a valid entry is received rather than having to run the program (while writing 'Quit' ends the the program).

I figure I could likely just create different classes for the main method (getting the date), check if its a leap year, a Conversion method, and maybe a validation method.

fvu
  • 32,488
  • 6
  • 61
  • 79
  • 1
    *Java* or *Javascript* ? – fvu Apr 02 '13 at 23:09
  • 1
    Don't reinvent the wheel, use a [`SimpleDateFormat`](http://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html) to parse to a `Calendar` then another `SimpleDateFormat` to format to a `String`. – Boris the Spider Apr 02 '13 at 23:13
  • What's the actual question here? The only question statement in all that information is "How can I also take that same date entered and convert it to a full written name?" to which the answer is just use `java.text.SimpleDateFormat` for which there are roughly 5 answers/day on SO to explain it :) If that's not allowed because it's an assignment, well, we're not going to just write your homework for you. Ask a specific question! – Affe Apr 02 '13 at 23:16
  • I meant to tag Java (thanks fvu!). My question is how I would write something like that. I can write everything separately but I have no idea how to make it all one program using different methods for do each part. Using SimpleDateFormat makes sense, but I probably shouldn't of asked for that much efficiency, the code behind that is important to see imo. Basically I'm asking what to do to call each method (if I can see how to write each part). – Dwelling Place Apr 02 '13 at 23:44

3 Answers3

1
public void testFormatDate() throws ParseException {
        final String[] suffixes =
                //    0     1     2     3     4     5     6     7     8     9
                { "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th",
                        //    10    11    12    13    14    15    16    17    18    19
                        "th", "th", "th", "th", "th", "th", "th", "th", "th", "th",
                        //    20    21    22    23    24    25    26    27    28    29
                        "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th",
                        //    30    31
                        "th", "st" };
        SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
        SimpleDateFormat odf = new SimpleDateFormat("MMMM"); // Gives month name.
        Calendar dayEntered = new GregorianCalendar();
        dayEntered.setTime(sdf.parse("04/02/2013"));
        System.err.println("You chose date: " + odf.format(dayEntered.getTime()) + " " + dayEntered.get(Calendar.DAY_OF_MONTH) + suffixes[dayEntered.get(Calendar.DAY_OF_MONTH)]
        + " " + dayEntered.get(Calendar.YEAR));
        System.err.println("This is " + (((GregorianCalendar)dayEntered).isLeapYear(dayEntered.get(Calendar.YEAR)) ? "" : "not ") + "a leap year.");

        System.err.println("This is day: " + dayEntered.get(Calendar.DAY_OF_YEAR));
    }
Uncle Iroh
  • 5,748
  • 6
  • 48
  • 61
  • Very efficient indeed, but I'd like to avoid SimpleDateFormat and call at least 3 methods to check if the year is a leap year, a valid date, and then the conversion things. Probably would be a lot of code to write. – Dwelling Place Apr 02 '13 at 23:59
1

Here's one way of doing it. The issue is that there is no way to make a SimpleDateFormatter print ordinal values for the day. I have shamelessly stolen the getDayOfMonthSuffix method from here.

public static void main(String[] args) {
    final String input = "4/2/2013";
    final SimpleDateFormat parser = new SimpleDateFormat("MM/dd/yyyy");
    final SimpleDateFormat formatter1 = new SimpleDateFormat("MMMM");
    final GregorianCalendar cal = (GregorianCalendar) GregorianCalendar.getInstance();
    final Date date;
    try {
        date = parser.parse(input);
        cal.setTime(date);
    } catch (ParseException ex) {
        System.out.println("Invalid input \"" + input + "\".");
        return;
    }
    if (cal.isLeapYear(cal.get(Calendar.YEAR))) {
        System.out.println("The year is a leap year");
    } else {
        System.out.println("The year is not a leap year");
    }
    System.out.println("The day of the year is " + cal.get(GregorianCalendar.DAY_OF_YEAR));
    final int dayOfMonth = cal.get(GregorianCalendar.DAY_OF_MONTH);
    System.out.println("The date is " +
            formatter1.format(date) +
            " " +
            dayOfMonth +
            getDayOfMonthSuffix(dayOfMonth) +
            ", " +
            cal.get(GregorianCalendar.YEAR));
}

static String getDayOfMonthSuffix(final int n) {
    if (n < 1 || n > 31) {
        throw new IllegalArgumentException("illegal day of month: " + n);
    }
    if (n >= 11 && n <= 13) {
        return "th";
    }
    switch (n % 10) {
        case 1:
            return "st";
        case 2:
            return "nd";
        case 3:
            return "rd";
        default:
            return "th";
    }
}
Community
  • 1
  • 1
Boris the Spider
  • 59,842
  • 6
  • 106
  • 166
  • @UncleIroh ha! This is a little ugly however, the lack of an ordinal format is certainly on oversight. – Boris the Spider Apr 02 '13 at 23:45
  • Yeah, I love your comment about shamelessly stealing from the other stack overflow question. I did the same :P – Uncle Iroh Apr 02 '13 at 23:46
  • I like how the getDayofMonth works (lol stolen though). However, I'm trying to figure out how I should hardcode (i guess) everything rather than using built in things like SimpleDateFormat. Like calling at least three different methods to do each thing. I figuring asking for the most efficient and basic way was my mistake. – Dwelling Place Apr 03 '13 at 00:02
  • @DwellingPlace sorry, but this isn't a code writing service where you specify the parameters of what you want and we fill in the blanks. This is the standard way to parse/format dates. If you want to do something different then you'll have to write it. Then, if you encounter a _specific_ problem you can post your code up and ask for help. – Boris the Spider Apr 03 '13 at 08:15
0

Since you need more of a framework as you say -- Here you go:

package com.yours

import java.io.Console;
import java.util.Calendar;

public class DoStuffWithADate {

    private Calendar parsedDate;

    public static void main(String[] args) {
        DoStuffWithADate soundsNaughty = new DoStuffWithADate();
        System.out.println("Enter a date my friend.  You should use the format: (MM/dd/yyyy)");
        Console theConsole = System.console();
        String enteredDate = theConsole.readLine();

        if (soundsNaughty.isValidDate(enteredDate)) {
            soundsNaughty.writeTheDateInNewFormat();
            soundsNaughty.writeIfItsALeapYear();
            soundsNaughty.writeTheDayOfYearItIs();
        }
    }

    private boolean isValidDate(String enteredDate) {
        //logic goes here.
        parsedDate = null;// if it's valid set the parsed Calendar object up.
        return true;
    }

    private void writeTheDateInNewFormat() {
        System.out.println("The new date format is: ");
    }

    private void writeIfItsALeapYear() {
        System.out.println("The year is a leap year.");
    }

    private void writeTheDayOfYearItIs() {
        System.out.println("The day of year is: ");
    }


}
Uncle Iroh
  • 5,748
  • 6
  • 48
  • 61
  • so where it says stuff like "writeTheDayofYearItIs()" I would include the code that takes the date input from the main method, do a little conversion, then print it? Why is calendar used? Is it necessary? I like the sense of humor added btw, it is uplifting and helps me remember x) – Dwelling Place Apr 03 '13 at 00:10
  • Yes, where it says "writeTheDayOfYearItIs()" you would include the code to do a little conversion then print it. Calendar isn't necessary, you could to it all manually. Calendar just supplies some handy code. – Uncle Iroh Apr 03 '13 at 14:45