2

I'm having a hard time with a few things. I'm fairly new to Java and I can't figure out how to read the first two digits to determine 08 or 09 due to the Octal digits. Also I'm getting a return of null, 1, 199 which don't need to be there. Help would be appreciated.

import java.util.*;
public class Dates {

    public static void main(String[] args) {

        String January,February, March, April, May, June, July, 
        August, September,October, November, December, month;

        January = February = March = April = May = June = July = 
                August = September = October = November = December = month = null;


        Scanner myScanner = new Scanner(System.in); 
        System.out.print("Enter date in the format mm/dd/yyyy: ");

        String input = myScanner.next();

        String months = input.substring(0,1);
        int monthInt = Integer.parseInt(months);

        if (monthInt == 01){
            month = January;
        }
        else if (monthInt == 02){
            month = February;
        }
        else if (monthInt == 03){
            month = March;
        }
        else if (monthInt == 04){
            month = April;
        }
        else if (monthInt == 05){
            month = May;
        }
        else if (monthInt == 06){
            month = June;
        }
        else if (monthInt == 07){
            month = July;
        }
        else if (monthDouble == 08){
            month = August;
        }
        else if (monthDouble == 09){
            month = September;
        }
        else if (monthInt == 10){
            month = October;
        }
        else if (monthInt == 11){
            month = November;
        }
        else if (monthInt == 12){
            month = December;
        }
        else {
            System.out.println("Invalid Month");
        }

        String days = input.substring(3,4);
        int daysInt = Integer.parseInt(days);

        if ((daysInt <= 31) && (monthInt == 1 || monthInt == 3 || monthInt ==
                5 || monthInt == 7 || monthInt == 8 || monthInt == 10 || monthInt
                == 12)){
            daysInt = daysInt;
        }
        else if ((daysInt <= 30) && (monthInt == 4 || monthInt == 6 || monthInt
                == 9 || monthInt == 11)){
            daysInt = daysInt;
        }
        else if ((daysInt <= 28) && (monthInt == 2)){
            daysInt = daysInt;
        }
        else
            System.out.println("Invalid Day");

        String year = input.substring(6,9);
        int yearInt = Integer.parseInt(year);

        if (yearInt >= 1900 && yearInt <= 2014) {
            yearInt = yearInt;
        }
        else {
            System.out.println("Year should be between 1900 and 2014");
        }

        String checkSlash = input.substring(2);
        char slash = checkSlash.charAt(0);

        if (slash == '/')
            slash = slash;
        else
            System.out.println("Invalid format. Use mm/dd/yyyy");

        System.out.println(month + " " + daysInt + ", " + year);

    }
}
ccjmne
  • 9,333
  • 3
  • 47
  • 62
user3256045
  • 21
  • 1
  • 1
  • 2
  • Look, I know that `java.util.Calendar` and `java.util.Date` are bad, but is there some reason you're ***extremely*** adverse to using that? – Makoto Jan 31 '14 at 05:33
  • @Makoto May i know why they are bad? – Keerthivasan Jan 31 '14 at 05:46
  • @Octopus: Where to begin...they're mutable, they're inconsistent at representing data, dealing with them in a universal manner is a bit of a pain...there's a lot of reasons, which is why there's a new JSR out for fixing time and dates in Java 8. – Makoto Jan 31 '14 at 05:48
  • @Makoto oh really, thanks for the explanation. Let me check it out. – Keerthivasan Jan 31 '14 at 05:52
  • @user3256045 You need to learn some basics on handing date-time. Search StackOverflow for "java date" or "joda" to find *many* examples. Like [this one](http://stackoverflow.com/q/4216745/642706) or [this one](http://stackoverflow.com/q/2735023/642706). – Basil Bourque Jan 31 '14 at 08:19

4 Answers4

4

There are vastly better ways to do this, most notably using even Java's Date and SimpleDateFormat classes, but if you must know...

Don't include the leading zero on the integers. You're not going to be reading or otherwise dealing with octal values. January is the first month, and it's much more straightforward to represent it as 1.

I'll give you an alternative, if you really don't want to use SimpleDateFormat. Consider that we know the values all fall in an integral range (that is, they're all going to be less than 2.1 billion). If we let the Integer class do the work of parsing the value for us, then we can do this in much less code.

Further to that, we don't need to worry about weird substrings (which, by the way, yours will only grab the first element - which is problematic).

Let's use the String#split() method and break up the input string on forward slashes.

String[] brokenInput = input.split("/");

Now we're given by our format and convention that the month is in brokenInput[0], the day in brokenInput[1], and the year in brokenInput[2].

Parsing is easy then:

Integer monthInt = Integer.parseInt(brokenInput[0]);
Integer daysInt = Integer.parseInt(brokenInput[1]);
Integer yearInt = Integer.parseInt(brokenInput[2]);
Makoto
  • 104,088
  • 27
  • 192
  • 230
  • Ok so if the month is in brokenInput[0] how would I check the input to see if its is Jan, Feb, etc.? I've never used that method before. – user3256045 Jan 31 '14 at 05:54
  • Well, that's just the thing - the array is only the result of the decomposition. What you actually *care* about is the parsed result, which is still `monthInt`. You then perform extra parsing on it. But, before you get too complacent with this ideology, [please read the trails on Dates and Time](http://docs.oracle.com/javase/tutorial/i18n/format/dateintro.html). It will help you ***immensely.*** – Makoto Jan 31 '14 at 05:56
  • If i switched and used the DateFormat class wouldn't I have to change most of my code? At least the month section. – user3256045 Jan 31 '14 at 06:02
  • Yes. But this isn't a bad thing. Despite the egregious mistakes that `Date` and `Calendar` have made, you won't be trying to reinvent the wheel. – Makoto Jan 31 '14 at 06:03
  • So how would I go about doing that? – user3256045 Jan 31 '14 at 06:08
2

try this for a simpler way

String strDate = "11/29/2009";
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
Date dateStr = formatter.parse(strDate);
Software Engineer
  • 15,457
  • 7
  • 74
  • 102
Scary Wombat
  • 44,617
  • 6
  • 35
  • 64
1

Java will consider numbers with leading zeros as octals, and a digit in octal base cannot be larger than 7. You will get an error if you try to use 08, 09. You could use Strings instead:

if (months.equals("01"))
    ...

And I think (since you want to compare with "01", "02", ...) you should use substring(0,2):

String months = input.substring(0,2);
Christian Tapia
  • 33,620
  • 7
  • 56
  • 73
0

I'm going to assume that there is a reason why you are doing this the long way.

To start with, removing the leading 0 of your int values when checking the month, they convert the value to octal, which you don't need...

if (monthInt == 1) {
    month = January;
} else if (monthInt == 2) {
    month = February;
} else if (monthInt == 3) {
    month = March;
} else if (monthInt == 4) {
    month = April;
} else if (monthInt == 5) {
    month = May;
} else if (monthInt == 6) {
    month = June;
} else if (monthInt == 7) {
    month = July;
} else if (monthInt == 8) {
    month = August;
} else if (monthInt == 9) {
    month = September;
} else if (monthInt == 10) {
    month = October;
} else if (monthInt == 11) {
    month = November;
} else if (monthInt == 12) {
    month = December;
} else {
    System.out.println("Invalid Month");
}

This...

String months = input.substring(0, 1);

Will get the first character of the input, but you've asked the user for mm/dd/yyyy, which suggests that you want a two digit value for the month and day...besides, what happens if they type in 12?

Instead you could use String[] parts = input.split("/"); to split the input String on the / delimiter, this (if the input is valid) will give you three elements, one each part of the date value.

Then you can use...

int monthInt = Integer.parseInt(parts[0]);
//...
int daysInt = Integer.parseInt(parts[1]);
//...
int yearInt = Integer.parseInt(parts[2]);

To convert the individual elements.

This raises the question that you should probably validate the input value in some meaningful way BEFORE you try and split it.

The month values are all null

String January, February, March, April, May, June, July,
       August, September, October, November, December, month;

January = February = March = April = May = June = July
        = August = September = October = November = December = month = null;

Which basically means you output will always start with null. You actually need to assign these some meaningful value.

I'll also parrot what every body else has said, unless you have a really good reason to do otherwise, I'd be using Calendar and some kind of DateFormat to do all this...

Updated with a (slightly over the top) example

This basically takes your idea and use SimpleDateFormat and Calendar to perform the actual checking of the input, for example...

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Scanner;

public class Dates {

    public static void main(String[] args) {
        Scanner kb = new Scanner(System.in);
        System.out.println("Date (mm/dd/yyyy):");
        String input = kb.nextLine();
        // This is a little excessive, but does a pre-check of the basic
        // format of the date.  It checks for a strict adhereance to
        // the nn/nn/nnnn format.  This might not be required as 
        // SimpleDateFormat can actually be configured to be lient in it's
        // parsing of values
        if (input.matches("[0-9]{2}/[0-9]{2}/[0-9]{4}")) {
            try {
                // Parse the String input to a Date object
                SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
                Date date = sdf.parse(input);
                // Create a Calendar, going to use this to compare the resulting
                // Date value, as the parser will auto correct the input
                Calendar cal = Calendar.getInstance();
                cal.setTime(date);

                // Split the basic input along the / delimeter
                String parts[] = input.split("/");
                boolean valid = true;
                // Check each part to make sure it matches the components of the date
                if (Integer.parseInt(parts[0]) != cal.get(Calendar.MONTH) + 1) {
                    valid = false;
                    System.out.println(parts[0] + " is not a valid month");
                } 
                if (Integer.parseInt(parts[1]) != cal.get(Calendar.DATE)) {
                    valid = false;
                    System.out.println(parts[1] + " is not a valid day of the month");
                } 
                if (Integer.parseInt(parts[2]) != cal.get(Calendar.YEAR)) {
                    valid = false;
                    System.out.println(parts[2] + " is not a valid year");
                }

                if (valid) {
                    // Print the result...
                    System.out.println(new SimpleDateFormat("MMMM dd, yyyy").format(date));
                }
            } catch (ParseException ex) {
                System.out.println("Unable to parse " + input + "; invalid format");
            }
        } else {
            System.out.println("Invalid format");
        }
    }

}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366