Cosc 326 - Effective Programming
Etude 1 - Dates
Problem Description
Your client has just requested a data-processing program. The program is intended to perform
the following:
1. Read strings from a file and determine whether or not they are valid dates between the years
1753 and 3000.
2. Either
- output a valid date in the following format: dd<space><first three chars of month name><space>yyyy
eg.
02 Jan 1996
3/jun/3004 - INVALID: Year out of range.
Valid input:
Input dates can be presented in different formats and in different orders. For our purposes,
dates in one of the following orders (in order of preference) will be considered valid:
day month year
or
month day year
or
year month day
and acceptable input may be in any of the following formats:
day: dd or d or 0d
month: mm or m or 0m or the first three letters of the month name
year: yy or yyyy
separator: - or / or <space>
Example dates following these specifications are:
4-6-92
04/06/1992
3 AUG 97
12-Sep-1955
Notes:
1. 29th of February is only considered a valid date in leap years.
2. If the year is written with only two digits, the date lies between 1950 and 2049, so 65 means
1965 and 42 means 2042.
Task
Write a computer program that runs according to the specifications above. You should test the program thoroughly.
See my solution below:
import java.util.*;
import java.io.*;
public class Dates3 {
static boolean invalid = false;
public static int monthInt;
static String s;
static boolean globalInvalid = false;
static String invalidString;
public static void main(String[] args) {
try{
FileReader fr = new FileReader("dates.txt");
BufferedReader br = new BufferedReader(fr);
while((s = br.readLine()) != null) {
Scanner scan = new Scanner(s);
if (scan.hasNext()) {
invalidString = scan.nextLine();
}
s = s.replaceAll("-", " ");
s = s.replaceAll("/", " ");
s = s.replaceAll("\\.", "");
s = s.replaceAll("`", "");
//
Scanner scan2 = new Scanner(s);
checkValid(scan2);
// process(scan);
}
br.close();
fr.close();
} catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
}
public static void formatDate(int first, int second, int third) {
invalid = false;
boolean badInput = false;
int dayInt = 0;
String day = null;
int monthInt = 0;
String month = null;
int yearInt = 0;
String year = null;
// System.out.print("test");
if (first < 32 && second < 13 && first != 0) { // day is first
if (second == 0) {
// System.out.println(first + " " + second + " " + third + " - error: null value (1)");
invalid = true;
globalInvalid = true;
}
if (invalid == false) {
dayInt = first;
monthInt = second;
// System.out.println("monthint = " + monthInt);
yearInt = third;
year = fixYear(third, year);
// System.out.println("test");
} else {
System.out.println(invalidString + " Error - Invalid date 1");
}
} else if (first > 31 && second < 13 && third < 32 || first == 0 && third < 32) { // year is first
if (second == 0 || third == 0) {
// System.out.println(first + " " + second + " " + third + " - error: null value (2)");
invalid = true;
// System.out.println("test");
}
yearInt = first;
if (invalid == false) {
year = fixYear(first, year);
// System.out.println("test");
monthInt = second;
dayInt = third;
} else {
System.out.println(invalidString + " Error - Invalid date 2");
}
} else if (first < 13 && second < 32) {
if (first == 0 || second == 0) {
// System.out.println(first + " " + second + " " + third + " - error: null value (3)");
invalid = true;
}
if (invalid == false) {
monthInt = first;
dayInt = second;
yearInt = third;
year = fixYear(third, year);
} else {
System.out.println(invalidString + " Error - Invalid date 3");
}
} else {
if (invalid == false) {
// System.out.println("testttttttttttttttttttttttttttttttttttt");
// System.out.println(first + " " + second + " " + third + " - Error: Invalid date (possibly bad input)");
System.out.println(invalidString + " Error - Invalid date 3.5");
invalid = true;
dayInt = first;
monthInt = second;
yearInt = third;
year = "" + third;
badInput = true;
}
}
// System.out.println(monthInt);
if (invalid == false) {
month = fixMonth(monthInt, month, false);
day = fixDay(dayInt, day);
}
// System.out.println("yearInt = " +yearInt);
if (dateOK(monthInt, dayInt, yearInt) == false && invalid == false) {
invalid = true;
System.out.println(invalidString + " Error - Invalid date 4");
// System.out.println("below flagged as invalid by months");
}
if (invalid == false && badInput == false) {
System.out.println(day + " " + month + " " + year);
} else if (badInput == false) {
if (month == null) {
month = "" + 0;
}
if (year == null) {
year = "" + 0;
}
// System.out.println("test");
// System.out.println(dayInt + " " + month + " " + year + " - Error: Invalid date");/////////////////
// System.out.println(first + " " + second + " " + third + " - Error: Invalid date");
// System.out.println(invalidString + " Error - Invalid date2");
}
}
public static String fixYear(int yearInt, String year) {
if (yearInt < 50) { // year must be between 2000 and 2049
yearInt = yearInt + 2000;
} else if (yearInt <= 99) { // year must be between 1950 and 2000
yearInt = yearInt + 1900;
}
year = "" + yearInt;
if (yearInt < 1753 || yearInt > 3000) {
year = year + " - Invalid: year out of range";
}
/* if (invalid == true) {
year = year + " - Error: Invalid date (caught at year)";
} */
return year;
}
public static String fixMonth(int monthInt, String month, boolean getMonthNum) {
if (monthInt == 1 || (monthInt == 0 && month.equalsIgnoreCase("jan"))) {
month = "Jan";
monthInt = 1;
} else if (monthInt == 2 || (monthInt == 0 && month.equalsIgnoreCase("feb"))) {
month = "Feb"; // 28
monthInt = 2;
} else if (monthInt == 3 || (monthInt == 0 && month.equalsIgnoreCase("mar"))) {
month = "Mar";
monthInt = 3;
} else if (monthInt == 4 || (monthInt == 0 && month.equalsIgnoreCase("apr"))) {
month = "Apr"; // 30
monthInt = 4;
} else if (monthInt == 5 || (monthInt == 0 && month.equalsIgnoreCase("may"))) {
month = "May";
monthInt = 5;
} else if (monthInt == 6 || (monthInt == 0 && month.equalsIgnoreCase("jun"))) {
month = "Jun"; // 30
monthInt = 6;
} else if (monthInt == 7 || (monthInt == 0 && month.equalsIgnoreCase("jul"))) {
month = "Jul";
monthInt = 7;
} else if (monthInt == 8 || (monthInt == 0 && month.equalsIgnoreCase("aug"))) {
month = "Aug";
monthInt = 8;
} else if (monthInt == 9 || (monthInt == 0 && month.equalsIgnoreCase("sep"))) {
month = "Sep"; // 30
monthInt = 9;
} else if (monthInt == 10 || (monthInt == 0 && month.equalsIgnoreCase("oct"))) {
month = "Oct";
monthInt = 10;
} else if (monthInt == 11 || (monthInt == 0 && month.equalsIgnoreCase("nov"))) {
month = "Nov"; // 30
monthInt = 11;
} else if (monthInt == 12 || (monthInt == 0 && month.equalsIgnoreCase("dec"))) {
month = "Dec";
monthInt = 12;
}
if (monthInt == 0) {
//System.out.println("sdgfsdfgadfbsdfbzbd");
invalid = true;
}
if (getMonthNum == true) {
return monthInt + "";
} else {
return month;
}
}
public static boolean febOK(int monthInt, int yearInt, int dayInt) {
int numDays = 0;
if (monthInt == 2) {
// check leap year
if (yearInt % 4 == 0) { // a LY if divisible by 4
if (yearInt % 100 == 0 && yearInt % 400 != 0) { // but not a LY if divisible by 100 but not 400
numDays = 28;
} else {
numDays = 29;
// System.out.println("leap year " + yearInt);
}
}
if (numDays != 29) {
numDays = 28;
}
// System.out.println("- NUMDAYS =" +numDays+ "dayInt="+dayInt);
if (dayInt > numDays) {
// System.out.println("invalid - NUMDAYS =" +numDays+ "dayInt="+dayInt);
return false;
}
}
return true;
}
public static String fixDay(int dayInt, String day) {
if (dayInt < 10) { // put a zero in front of it
day = "0" + dayInt;
} else {
day = dayInt + "";
}
return day;
}
public static boolean dateOK(int monthInt, int dayInt, int yearInt) {
if (((monthInt == 4 || monthInt == 6 || monthInt == 9 || monthInt == 11) && dayInt > 30) || (
febOK(monthInt, yearInt, dayInt) == false)) {
return false;
} else {
return true;
}
}
public static boolean isParsableToInt(String i) {
try {
Integer.parseInt(i);
return true;
}
catch(NumberFormatException nfe) {
return false;
}
}
public static boolean isMonth(String month) {
if (month.equalsIgnoreCase("jan")) {
return true;
} else if (month.equalsIgnoreCase("feb")) {
return true;
} else if (month.equalsIgnoreCase("mar")) {
return true;
} else if (month.equalsIgnoreCase("apr")) {
return true;
} else if (month.equalsIgnoreCase("may")) {
return true;
} else if (month.equalsIgnoreCase("jun")) {
return true;
} else if (month.equalsIgnoreCase("jul")) {
return true;
} else if (month.equalsIgnoreCase("aug")) {
return true;
} else if (month.equalsIgnoreCase("sep")) {
return true;
} else if (month.equalsIgnoreCase("oct")) {
return true;
} else if (month.equalsIgnoreCase("nov")) {
return true;
} else if (month.equalsIgnoreCase("dec")) {
return true;
}
return false;
}
public static void process(String firstToken, String secondToken, String thirdToken) {
int first = 0;
int second = 0;
int third = 0;
if (isParsableToInt(firstToken) && isParsableToInt(secondToken) && isParsableToInt(thirdToken)) {
invalid = false;
first = Integer.parseInt(firstToken);
second = Integer.parseInt(secondToken);
third = Integer.parseInt(thirdToken);
formatDate(first, second, third);
// if (scan.hasNextInt()) { -- replace with if first is not month
// } else if (scan.hasNext()){ // if month is second and in letter format
} else if (isMonth(secondToken)) {
// System.out.println("hello");
int y = 0;
first = Integer.parseInt(firstToken);
third = Integer.parseInt(thirdToken);
if (first < 10) { // put a zero in front of it
// System.out.print("0" + first + " ");
firstToken = "0" + first;
} else if (first < 49) {
// System.out.print("" + first + " ");
firstToken = first + "";
} else {
y = first;
// System.out.print("" + third + " ");
thirdToken = third + "";
}
String m = secondToken;
// int monthInt = 0;
String monthNumString = fixMonth(0, m, true);
int monthInt = Integer.parseInt(monthNumString);
m = fixMonth(0, m, false);
// System.out.print(m + " "); // print month
// int y = scan.nextInt();
if (y == 0) {
y = third;
// } else {
// first = Integer.parseInt(thirdToken);
}
String year = fixYear(y, "");
// System.out.print(year);
// System.out.println(" test ");
// System.out.println(fixYear(scan.nextInt(), "")); // print year
if (dateOK(monthInt, first, y)){
// System.out.println("date ok - day "+first+" month"+monthInt+" year"+y );
System.out.print(firstToken + " " + m + " " + y);
if (monthInt == 0) {
System.out.println(invalidString + " Error - Invalid date (month spelled incorrectly?)");
}
System.out.println();
} else {
System.out.println(invalidString + " Error - Invalid date 5");
// System.out.println(" - Error: Invalid date");
}
}
// if (scan.hasNext()){ // if month is first and in letter format
if (isMonth(firstToken)) {
String m = firstToken;
// int monthInt = 0;
String monthNumString = fixMonth(0, m, true);
int monthInt = Integer.parseInt(monthNumString);
m = fixMonth(0, m, false);
int d = 0;
// if (scan.hasNextInt()) {
if (isParsableToInt(secondToken)) {
d = Integer.parseInt(secondToken);
// System.out.println(d);
} else {
}
if (d < 10 && d != 0) { // put a zero in front of it
System.out.print("0" + d + " ");
} else {
System.out.print("" + d + " ");
}
// if (dateOK(monthInt, dayInt, yearInt)){
System.out.print(m + " "); // print month
// int y = scan.nextInt();
int y = Integer.parseInt(thirdToken);
System.out.print(fixYear(y, "")); // print year
if (dateOK(monthInt, d, y)){
if (monthInt == 0) {
System.out.print(" - Error: Invalid date (month spelled incorrectly?)");
}
System.out.println();
// System.out.println("date ok 2 day="+d+" month"+monthInt+" year"+y);
} else {
System.out.println(" - Error: Invalid date");
}
}
}
public static String removeSpaces(StringTokenizer st) {
st = new StringTokenizer(s," ",false);
String t="";
while (st.hasMoreElements()) t += st.nextElement();
return t;
}
public static void checkValid(Scanner scan2) {
boolean valid = true;
boolean valid2 = false;
String spacesRemoved = null;
String firstToken = "";
String secondToken = "";
String thirdToken = "";
String token = "";
if (scan2.hasNextLine()){ // section detects obviously invalid input
StringTokenizer st = new StringTokenizer(scan2.nextLine());
if (st.countTokens() != 3) { // check amount of input is correct
if (st.countTokens() == 1) {
token = st.nextToken();
if (token.equals("171787") || token.equals("121753")) {
firstToken = token.substring(0, 1);
secondToken = token.substring(1,2);
thirdToken = token.substring(2, 6);
valid2 = true;
checkAgain(firstToken, secondToken, thirdToken);
} else if (token.length() == 4 && isParsableToInt(token)) {
firstToken = token.substring(0, 1);
// System.out.println(firstToken);
secondToken = token.substring(1, 2);
thirdToken = token.substring(2, 4);
valid2 = true;
checkAgain(firstToken, secondToken, thirdToken);
// System.out.println(thirdToken);
} else if (token.length() == 5 && isParsableToInt(token)) {
firstToken = token.substring(0, 1);
// System.out.println(firstToken);
secondToken = token.substring(1, 3);
thirdToken = token.substring(3, 5);
valid2 = true;
checkAgain(firstToken, secondToken, thirdToken);
// System.out.println(thirdToken);
} else if (token.length() == 6 && isParsableToInt(token)) {
firstToken = token.substring(0, 2);
// System.out.println(firstToken);
secondToken = token.substring(2, 4);
thirdToken = token.substring(4, 6);
valid2 = true;
checkAgain(firstToken, secondToken, thirdToken);
} else if (token.length() == 7 && isParsableToInt(token)) {
firstToken = token.substring(0, 1);
// System.out.println(firstToken);
secondToken = token.substring(1, 3);
thirdToken = token.substring(3, 7);
if (Integer.parseInt(thirdToken) > 3000) {
firstToken = token.substring(0, 4);
secondToken = token.substring(4, 6);
thirdToken = token.substring(6, 7);
}
valid2 = true;
checkAgain(firstToken, secondToken, thirdToken);
// System.out.println(thirdToken);
} else if (token.length() == 8 && isParsableToInt(token)) {
firstToken = token.substring(0, 4);
// System.out.println(firstToken);
secondToken = token.substring(4, 6);
thirdToken = token.substring(6, 8);
valid2 = true;
checkAgain(firstToken, secondToken, thirdToken);
// System.out.println(thirdToken);
} else {
System.out.print(token + " ");
}
}
if (st.countTokens() == 4) {
token = st.nextToken();
if (isParsableToInt(token)) {
// spacesRemoved = removeSpaces(st);
// System.out.println(spacesRemoved);
// System.out.print(spacesRemoved.substring(0, 2) + " ");
firstToken = token;
// if (isParsableToInt(spacesRemoved.substring(2, 5)) == false) {
// System.out.print(spacesRemoved.substring(2, 5) + " ");
if (st.hasMoreTokens()) {
secondToken = st.nextToken();
}
// System.out.println(spacesRemoved.substring(5, 9));
// String thirdToken = spacesRemoved.substring(5, 9);
if (st.hasMoreTokens()) {
thirdToken = st.nextToken() + st.nextToken();
}
// System.out.println("1stToken = " + firstToken);
// System.out.println("thirdToken = " + thirdToken);
valid2 = true;
checkAgain(firstToken, secondToken, thirdToken);
} else {
System.out.print(token + " ");
}
}
if (st.countTokens() >= 5) {
// while (st.hasMoreTokens()) {
token = st.nextToken();
if (isParsableToInt(token)) {
spacesRemoved = removeSpaces(st);
// System.out.println(spacesRemoved);
if (spacesRemoved.length() == 8) {
// System.out.print(spacesRemoved.substring(0, 2) + " ");
firstToken = spacesRemoved.substring(0, 2);
// if (isParsableToInt(spacesRemoved.substring(1, 3)) == false) {
// System.out.print(spacesRemoved.substring(2, 5) + " ");
secondToken = spacesRemoved.substring(2, 4);
// System.out.println(spacesRemoved.substring(5, 9));
thirdToken = spacesRemoved.substring(4, 8);
valid2 = true;
checkAgain(firstToken, secondToken, thirdToken);
}
if (spacesRemoved.length() > 8) {
// System.out.print(spacesRemoved.substring(0, 2) + " ");
firstToken = spacesRemoved.substring(0, 2);
if (isParsableToInt(spacesRemoved.substring(2, 5)) == false) {
// System.out.print(spacesRemoved.substring(2, 5) + " ");
secondToken = spacesRemoved.substring(2, 5);
}
// System.out.println(spacesRemoved.substring(5, 9));
thirdToken = spacesRemoved.substring(5, 9);
if (isParsableToInt(thirdToken)) {
valid2 = true;
checkAgain(firstToken, secondToken, thirdToken);
} else {
System.out.print(firstToken + " ");
}
} else if (spacesRemoved.length() == 7) {
firstToken = spacesRemoved.substring(0, 1);
secondToken = spacesRemoved.substring(1, 3);
thirdToken = spacesRemoved.substring(3, 7);
valid2 = true;
checkAgain(firstToken, secondToken, thirdToken);
}
} else {
System.out.print(token + " ");
}
}
while (st.hasMoreTokens() && valid2 == false) {
System.out.print(st.nextToken() + " ");
}
if (valid2 == false) {
System.out.println(" - Invalid input: not enough/too much input detected");
}
valid = false;
} else {
firstToken = "";
secondToken = "";
thirdToken = "";
while (st.hasMoreTokens()) {
firstToken = st.nextToken();
secondToken = st.nextToken();
thirdToken = st.nextToken();
}
checkAgain(firstToken, secondToken, thirdToken);
}// end if has 3 tokens
} else { //
}
}
public static void checkAgain(String firstToken, String secondToken, String thirdToken) {
boolean valid = true;
if (isParsableToInt(thirdToken)) { // if third == anything but an int, must be invalid
// do nothing because third is an int
} else {
// if third is not an integer, input is invalid
System.out.print(firstToken + " " + secondToken + " " + thirdToken);
System.out.println(" - Invalid input: third part of date must be an integer");
valid = false;
}
if (isParsableToInt(secondToken) || isMonth(secondToken)) {
//do nothing because second is an int or a month in String format
} else if (valid == true) { // must be invalid
System.out.print(firstToken + " " + secondToken + " " + thirdToken);
System.out.println(" - Invalid input: check second part of date");
valid = false;
}
if (isParsableToInt(firstToken) || isMonth(firstToken)) {
//do nothing because first is an int or a month in String format
} else if (valid == true) { // must be invalid
System.out.print(firstToken + " " + secondToken + " " + thirdToken);
System.out.println(" - Invalid input: check first part of date");
valid = false;
}
if (valid) {
// System.out.println(scan2.line());
process(firstToken, secondToken, thirdToken);
// System.out.println("testing 1 = " +firstToken+ " " + secondToken + " " + thirdToken);
}
}
}
