Question
Java program that will read dates from an external text file and identify which two dates in the file have the fewest number of days
Java program that will read dates from an external text file and identify which two dates in the file have the fewest number of
days between them and which two dates have the largest number of days between them and output those
pairs of dates and the number of days between each pair.
For this program, you will be provided with a
Date
class that you will use to store and process dates with so
that you don't have to manage that information manually. This should enable you to focus on the logic of the
program itself rather than adding in details of storing and processing the dates.
NOTE
: See later in the assignment for details on how the output should be formatted.
For this program, you will also need to implement at least two additional methods other than
main()
.
These
methods can accomplish whatever task you want them to, such as: read the file of dates, sort an array of
dates, display the list of dates, find the smallest range between two dates, find the largest range of dates
between two dates, etc.
The methods you write will need to have complete Javadoc documentation and be used (called) at least once
each during your program's execution.
It is acceptable to write more than two additional methods if you would like in order to practice breaking
programs into smaller, more manageable units of code.
Program 12 - Spring 2018
Overview of Program
Writing two methods on your own
The file that you will read dates from will look like this:
5
1/1/1900
1/2/1900
12/5/1798
7/4/3001
8/1/2028
The first value of the file will be an
int
value indicating how many dates will be present in the file.
The value
could be any value from
2
and up.
Each file will be guaranteed to have at least two dates in it.
Each date in the file will be on a line by itself and will be in the format of
MM/DD/YYYY
, where
MM
is the
month,
DD
is the day, and
YYYY
is the year. Information about easily processing dates in this format is
discussed later in this document.
For this program, all dates in a file will be valid dates, but functionality is provided within the
Date
class to
identify invalid dates and handle them appropriately.
There may be duplicate entries for the same date in the file.
Dates can be in the range
1/1/1753
to
12/31/3000
.
In order to process a file for input instead of keyboard input, you'll need to be able to open and read from a
separate text file in Java.
There are a number of different ways to do this, and you'll explore more involved
ways to process files if you take more programming courses, but for what we need this semester we'll create a
Scanner
that is attached to a file so that input will basically behave the same way that you've been
processing things all semester, just from a file instead of the keyboard.
To practice with this idea, first create a file named
test.txt
in the same directory that your program file will
reside in that looks like this:
Format of the file
Reading input from a file instead of the keyboard
5
51
2112
42
12
-123
Now edit a file called
TestingFileInput.java
in jGRASP and place the following code into it.
Compile
and run the code to see what it does.
Pay close attention to the
throws FileNotFoundException
code
added to the header of the
main()
method, which is new and only necessary right now when processing
external files:
import
java
.
util
.
Scanner
;
import
java
.
io
.
File
;
Import java
.
io
.
FileNotFoundException
;
public
class
TestingFileInput
{
public
static
void
main
(
String args
[
]
)
throws
FileNotFoundException
{
// Create a regular Scanner for keyboard input
Scanner keyboard
=
new
Scanner
(
System
.
in
)
;
// Now create a String variable and read the filename
System
.
out
.
println
(
"Enter input filename: "
)
;
String inFile
;
// Notice the use of the System.in Scanner for this input
inFile
=
keyboard
.
next
(
)
;
// Need to create a File variable based on the inFile file name
File file
=
new
File
(
inFile
)
;
// Now create a Scanner attached to the file instead of System.in
// This Scanner will be used for file input!!!
Scanner fileInput
=
new
Scanner
(
file
)
;
// Read something out of the file, which is an integer
int
v1
=
fileInput
.
nextInt
(
)
;
System
.
out
.
println
(
"First int of the file is : "
+
v1
)
;
// Set up a loop that reads the rest of the int data from the file
System
.
out
.
println
(
"Now reading the rest of the data!"
)
;
for
(
int
which
=
0
;
which
<
v1
;
which
++
)
{
int
v
=
fileInput
.
nextInt
(
)
;
System
.
out
.
printf
(
"A value from the file: %d "
,
v
)
;
}
}
}
Java
Your program may not compile with an error that looks like this:
FileInput.java:18: error: unreported exception FileNotFoundException;
must be caught or declared to be thrown
Scanner fileInput = new Scanner(file);
If this happens, make sure you go back and add in the
throws FileNotFoundException
code on the
main()
method header line.
This should take care of that situation.
You should notice that the example program creates two different
Scanner
variables.
Variable
keyboard
is used to read the filename from the keyboard, as we've been doing all semester so far.
Variable
fileInput
is connected to an external file to pull data from.
When you run the code and are prompted for a file name, enter
test.txt
or whatever you called the file
you created. If the file exists, the program should read the data from that file and output it to the screen.
Notice what happens when you enter a filename that doesn't exist; the program should exit with some sort of
error like this:
Exception in thread "main" java.io.FileNotFoundException: test.data
(No such file or directory)
at java.base/java.io.FileInputStream.open0(Native Method)
at java.base/java.io.FileInputStream.open(FileInputStream.java:196)
at java.base/java.io.FileInputStream.
at java.base/java.util.Scanner.
at FileInput.main(FileInput.java:18)
It is important and imperative that you work with this code until you are certain you have a good handle
on how it's setting up an external file for reading before moving on to the next part of the assignment.
The code doesn't compile with a really weird error!
The program uses multiple
Scanner
variables! What?
Okay, it compiles and runs ... what now?
A
Date
object can store a date between
1/1/1753
and
12/31/3000
.
Objects of
Date
class have the following public methods available for you to use.
Please note that
you do not need to write these methods; they are available for you to use in the
Date
class
that is provided in the
Date.class
file you will download.
You don't need to use any
import
statements or anything fancy to use the
Date
class. Just create a new
Date
object in your program using the constructor as described below and you can move forward from
there.
Method
Description and Example
Date()
Default constructor, used to create a new
Date
object. The
date is set to 1/1/1753.
Date d1 = new Date();
Date(int m, int d, int y)
Specific constructor, used to create a new
Date
object with
a given date.
Date d2 = new Date(11,27,2017);
setDate(int m, int d, int y)
Attempts to set the date to the given month
m
, day
d
,
and year
y
. Returns
true
if the date was valid.
Returns
false
and sets the date to 1/1/1753 if the attempted date
was invalid.
d1.setDate(4,1,2018);
daysSince1753()
Returns an
int
value denoting how many days since
1/1/1753 the object's date is.
int w = d2.daysSince1753();
toString()
Allows printing of the object's date.
System.out.print(d2);
What can objects of the
Date
class do?
The closest dates will be determined by comparing each date to all of the dates in the file except for itself.
The
result may be
0
, but only if there are duplicate dates in the file.
The furthest dates will also be determined by comparing each date to all of the dates in the file except itself.
Given the storage range of dates possible in a
Date
object, the maximum number of days between dates
could be
455821
.
See the sample runs at the end of the file for examples of different results.
For previous assignments when entering dates, the month, day, and year needed to be entered separately.
For
this assignment, you'll change a property of the
Scanner
attached to the file that you create so that you can
read dates in
MM/DD/YYYY
format.
By default, a
Scanner
uses whitespace like spaces and newlines (enter/return) to identify different pieces of
input, like this:
Scanner get
=
new
Scanner
(
System
.
in
)
;
System
.
out
.
(
"Enter your date: "
)
;
int
m
=
get
.
nextInt
(
)
;
int
d
=
get
.
nextInt
(
)
;
int
y
=
get
.
nextInt
(
)
;
Determining Closest and Furthest Dates
Closest Dates
Furthest Dates
Examples
Considerations for Entering and Validating Dates
Entering Dates
Java
Input to this code could be entered like this:
Enter your date: 4
16
2018
or like this:
Enter your date: 4 16 2018
Either way, variable
m
would get a value of
4
, variable
d
would get a value of
16
and variable
y
would get a value of
2018
.
In order to enter dates in MM/DD/YYYY format, using slashes, the
Scanner
attached to your file needs to
behave differently. The easiest way to do this is to change the way the
Scanner
reads values from the
keyboard.
As mentioned in the last section, a
Scanner
uses whitespace as a delimiter between input by
default.
To change this behavior, you can use the
useDelimiter()
method from the
Scanner
class.
More information about the
useDelimiter()
method can be found at
http://bit.ly/scannerdelimiter
.
To enable a
Scanner
to use, for instance, slashes
/
as delimiters in addition to spaces, you can use the
following code in your program:
Scanner get
=
new
Scanner
(
System
.
in
)
;
get
.
useDelimiter
(
"[/\\s+]+"
)
;
// notice two backslashes here!
System
.
out
.
(
"Enter your date: "
)
;
int
m
=
get
.
nextInt
(
)
;
int
d
=
get
.
nextInt
(
)
;
int
y
=
get
.
nextInt
(
)
;
Now, dates can be entered in any of the following four ways:
Enter your date: 4
16
2018
Changing
Scanner
behavior
Java
or
Enter your date: 4 16 2018
or
Enter your date: 4/16/2018
or
Enter your date: 4 / 16 / 2018
The
useDelimiter()
method changes the behavior of the
Scanner
by providing a list of items that can
be seen as delimiters between pieces of information.
[/\\s+]+
tells Java that it can use either a forward
slash
/
or a whitespace character
\s
(such as space, return, etc) to identify different inputs.
The key to having this work with input from a text file is to apply the
.useDelimiter()
method to the
Scanner
you would like to change the behavior of. So, if you have a
Scanner
attached to a file, then you
want to use the
.useDelimiter()
method on that
Scanner
.
The output of your program should look like the following sample:
Enter filename to process: d1.txt
The sorted dates from the file are:
1: 11/30/1955
2: 11/23/2015
3: 11/24/2015
4: 11/25/2015
5: 11/26/2015
6: 11/28/2015
7: 11/29/2015
8: 11/30/2015
9: 12/02/2015
10: 02/23/2016
Closest (1): 11/23/2015 and 11/24/2015
Furthest (22000): 11/30/1955 and 02/23/2016
Make sure to include the following items in the format seen above:
The program should output a list of the dates themselves, one per line, sorted from earliest date to latest
date.
Then output the dates that are "closest" to each other, including the number of days between the two
dates, in "sorted" order with the earlier date listed first.
Finally, output the dates that are the "furthest" from each other, including the number of days between the
two dates, in sorted order with the earlier date listed first.
The starter code can be found below:
import java.util.Scanner; import java.io.File; import java.io.FileNotFoundException;
public class FileOfDates { /** * It's the main method! * @param args Arguments to the main method * @throws Exception is a file-related exception we're not processing */
public static void main(String args[]) throws FileNotFoundException { // The Scanner named get is for keyboard input Scanner get = new Scanner(System.in); System.out.print("Enter filename to process: "); String fn = get.next();
// The File thing attempts to connect to a file named in variable fn File thing = new File(fn); // The Scanner named fileInput is for reading data from the user Scanner fileInput = new Scanner(thing); // The following statement changes default behavior of this file // Scanner; see assignment for more information fileInput.useDelimiter("[/\\s]+");
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started