Question
Topics Covered: Programming with the String class (Java)
1 Introduction
Many programs have to manipulate String objects in interesting ways. The String class is also well designed and provides many useful methods. So, this assignment will give you some practice with it. Your task will be to parse dates written in a variety of formats and convert them into a standard format. Your program will read a line of dates separated by pound signs (#) and determine which kind of date was read.
2 Date formats
Your program will parse a line of dates written in three different styles: Dash-dates, month-first,and day- first. Here is a sample input line that you will have to handle:
25 Sept 2014 #February 25, 1960#12 -25 -2000# Janu 27,2017
This line contains four dates written in the three different formats. Notice also that space characters can appear in lots of places. Your program must handle three different date formats:
Dash-dates: month, day, and year entered as numbers with Dashes between them. There can be spaces around the numbers and Dashes, but spaces are not allowed within the numbers.
Example of a valid date:12 -25 -2017
Day first: The day of the month is given as a number, followed by the month written as a word or abbreviation (of at least three letters), followed by the year. The month string can be in any mix of lower-case and upper-case characters. Spaces should separate the three parts. No spaces are allowed within the numbers or month name.
Example of a valid date:12 September 2017
Month first: The month written as a word or abbreviation, followed by the day, then a comma, and then the year. A space must separate the month and day and there may be any number of spaces around the three parts of the date and the comma.
Example of a valid date:March 27,1990
You may assume that any date containing a Dashes is in Dashes date format. You may assume that any date containing a comma is in Month-First format. You may assume that any other date is in Day-First format.
3 Requirements
• Your program must read a single line that may contain many dates in any of the formats. It will print each date that is valid in Day-First format, always with the full month name, with the first letter of the month name in upper-case. The Sample Output below gives an example of what your program should produce.
1
Your program must give an error message whenever a date is invalid. It should give a specific error message in the following cases:
– A month name or abbreviation is misspelled or too short(less that three characters).
– A day or month number is too low or too high. Months must be between 1 and 12. Days must
be valid for the month (ignoring leap years).
– A year number is too low(years less than 1900 are too low).
– There are too many Dashes in a Dashes-Date.
For this assignment, it is OK if your program crashes when calling Integer.parseInt and the argument is not a valid integer.
– These crashes can be avoided. One way would be to write your own code to check whether the String is valid for an integer. Another way would be to catch the exception that is thrown, but we wont teach how to do that until Chapter 15.
4 Implementation
We have some specific requirements for how you write the program. We are trying to show you a way to write programs that is more organized and is typical of what professional programmers would do. Here are the requirements:
Use the below build-in methods
– From the String class: substring, trim, split, toLowerCase, indexOf, or lastIndexOf
– From the Integer class: parseInt
In the main(), prompt the user, reads in the line of dates, breaks the line into separate date strings,
and for each strings, prints “Date <number>: ” and calls the appropriate parsing method.
One method for parsing each kind of date. These methods either output an error message or the
corresponding standard date string.
– public static void parseDashDate(String dateStr)
– public static void parseMonthFirstDate(String dateStr) – public static void parseDayFirstDate(String dateStr)
public static int monthToNum(String mStr)
– takes a string that should be the name or abbreviation of the month name and returns the number
of the month. It returns zero if the name doesn’t match any month or is too short.
public static boolean isValidMonthDay(int day, int month)
– returns true if the month and day numbers form a valid day of a year (in a non-leap-year).
public static boolean isValidYear(int year)
– returns true if the year is valid.
public static String standardDateString(int day, int month, int year)
– takes the day, month, and year as numbers and returns a String containing that date in day- month-year format (e.g. 21 March 2017)
public static boolean isValidMonthAbbreviation(String month)
takes the month as a string and returns boolean value. True, if the passed month string represent
a valid month string(the length of the trimmed month string is greater than or equals to 3, and the month string abbreviation is correctly spelled.
2
5 Sample Output
Explanation / Answer
/** * @fileName ParseDate.java * @author * @since 8/2/17 */ package datefromat; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.Scanner; public class ParseDate { public static void parseDashDate(String dateStr) { String[] date = dateStr.split("-"); if (date.length > 3) { System.out.print("ERROR: Too many Dashes"); } else { int day = Integer.parseInt(date[1].trim()); int month = Integer.parseInt(date[0].trim()); int year = Integer.parseInt(date[2].trim()); if (isValidYear(year)) { if (isValidMonthDay(day, month)) { System.out.print(standardDateString(day, month, year)); } else { System.out.print("ERROR: Invalid month or day number"); } } else { System.out.print("ERROR: Invalid year"); } } } public static void parseMonthFirstDate(String dateStr) { String[] dateString = dateStr.split(","); int year = Integer.parseInt(dateString[1].trim()); String[] month_date = dateString[0].trim().split(" "); if (isValidMonthAbbreviation(month_date[0].trim())) { if (isValidYear(year)) { int month = monthToNumber(month_date[0].trim()); int day = Integer.parseInt(month_date[1].trim()); if (isValidMonthDay(day, month)) { System.out.print(standardDateString(day, month, year)); } else { System.out.print("ERROR: Invalid month or day number"); } } else { System.out.print("ERROR: Invalid year"); } } else{ System.out.print("ERROR: Invalid Month String"); } } /** * * @param dateStr */ public static void parseDayFirstDate(String dateStr) { String[] dateString = dateStr.split(" "); int year = Integer.parseInt(dateString[2].trim()); ; if (isValidYear(year)) { if (isValidMonthAbbreviation(dateString[1].trim())) { int month = monthToNumber(dateString[1].trim()); int day = Integer.parseInt(dateString[0].trim()); if (isValidMonthDay(day, month)) { System.out.print(standardDateString(day, month, year)); } else { System.out.print("ERROR: Invalid month or day number"); } } else { System.out.print("ERROR: Invalid month"); } } else { System.out.print("ERROR: Invalid year"); } } /** * * @param month * @return */ public static int monthToNumber(String month) { int monthNumber = 0; if (month.toLowerCase().equals("jan") || month.toLowerCase().equals("january")) { monthNumber = 1; } else if (month.toLowerCase().equals("feb") || month.toLowerCase().equals("february")) { monthNumber = 2; } else if (month.toLowerCase().equals("march")) { monthNumber = 3; } else if (month.toLowerCase().equals("apr") || month.toLowerCase().equals("april")) { monthNumber = 4; } else if (month.toLowerCase().equals("may")) { monthNumber = 5; } else if (month.toLowerCase().equals("june")) { monthNumber = 6; } else if (month.toLowerCase().equals("jul") || month.toLowerCase().equals("july")) { monthNumber = 7; } else if (month.toLowerCase().equals("aug") || month.toLowerCase().equals("august")) { monthNumber = 8; } else if (month.toLowerCase().equals("sep") || month.toLowerCase().equals("september")) { monthNumber = 9; } else if (month.toLowerCase().equals("oct") || month.toLowerCase().equals("october")) { monthNumber = 10; } else if (month.toLowerCase().equals("nov") || month.toLowerCase().equals("november")) { monthNumber = 11; } else if (month.toLowerCase().equals("dec") || month.toLowerCase().equals("december")) { monthNumber = 12; } return monthNumber; } /** * * @param day * @param month * @return */ public static boolean isValidMonthDay(int day, int month) { boolean result = false; if (month != 2) { if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) { if (day > 0 && day 0 && month 0 && day 0 && day = 1900) { result = true; } return result; } /** * * @param day * @param month * @param year * @return */ public static String standardDateString(int day, int month, int year) { String monthString = ""; switch (month) { case 1: monthString = "January"; break; case 2: monthString = "February"; break; case 3: monthString = "March"; break; case 4: monthString = "April"; break; case 5: monthString = "May"; break; case 6: monthString = "June"; break; case 7: monthString = "July"; break; case 8: monthString = "August"; break; case 9: monthString = "September"; break; case 10: monthString = "October"; break; case 11: monthString = "November"; break; case 12: monthString = "December"; break; } return "" + day + " " + monthString + " " + year; } /** * * @param month * @return */ public static boolean isValidMonthAbbreviation(String month) { boolean result = false; if (month.length() > 2) { if (month.toLowerCase().equals("jan") || month.toLowerCase().equals("january")) { result = true; } else if (month.toLowerCase().equals("feb") || month.toLowerCase().equals("february")) { result = true; } else if (month.toLowerCase().equals("march")) { result = true; } else if (month.toLowerCase().equals("apr") || month.toLowerCase().equals("april")) { result = true; } else if (month.toLowerCase().equals("may")) { result = true; } else if (month.toLowerCase().equals("june")) { result = true; } else if (month.toLowerCase().equals("jul") || month.toLowerCase().equals("july")) { result = true; } else if (month.toLowerCase().equals("aug") || month.toLowerCase().equals("august")) { result = true; } else if (month.toLowerCase().equals("sep") || month.toLowerCase().equals("september")) { result = true; } else if (month.toLowerCase().equals("oct") || month.toLowerCase().equals("october")) { result = true; } else if (month.toLowerCase().equals("nov") || month.toLowerCase().equals("november")) { result = true; } else if (month.toLowerCase().equals("dec") || month.toLowerCase().equals("december")) { result = true; } } return result; } public static void main(String[] args) { System.out.println("Welcome to the CS251 Date Parser!"); Scanner sc = new Scanner(System.in); System.out.print("Enter line of dates:"); String dateString =sc.nextLine().trim(); String[] dateArray = dateString.split("#"); int count = 1; if (dateString.length() > 0) { for (String s : dateArray) { if (s.length() < 3) { System.out.print("Date " + count + ":"); System.out.println("ERROR: No date entered"); System.out.println(); count++; } else if (s.contains("-")) { System.out.print("Date " + count + ":"); parseDashDate(s); System.out.println(); count++; } else if (s.contains(",")) { System.out.print("Date " + count + ":"); parseMonthFirstDate(s); System.out.println(); count++; } else { System.out.print("Date " + count + ":"); parseDayFirstDate(s); System.out.println(); count++; } } } else { System.out.println("ERROR:Empty Line"); } System.out.println("Goodbye!!"); } }