问题
I'm working on an assignment, and my goal is to create a class that prints the day of the week given a date. When prompted for input, if the user enters nothing, the program is stopped. Otherwise, if the user enters a date, the program provides the day of the week and then continues to re-prompt the user. The date the user inputs will be in the format of m d y, or for example, 1 10 2017 for January 10th, 2017.
What I have so far does everything I need, except it uses the current day, month, and year instead of the user inputted day, month, and year.
import java.util.Calendar;
import java.util.Scanner;
public class FindDayOfWeek {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("Repeatedly enter a date (m d y) to get the day of week. Terminate input with a blank line.");
String date = s.nextLine();
while (true) {
if (date.isEmpty()) {
System.exit(0);
}
else {
Calendar c = Calendar.getInstance();
String[] days = new String[] {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
System.out.println("Day of week is " + days[c.get(Calendar.DAY_OF_WEEK) - 1]);
System.out.println("Repeatedly enter a date (m d y) to get the day of week. Terminate input with a blank line.");
date = s.nextLine();
}
}
}
}
I know what needs to be replaced is the second to last chunk of code that says c.get(Calendar.DAY_OF_WEEK), however I do not know what I can use to replace it in order to get the user inputted date.
I know there are other packages that can solve the same problem, however, I'm required to use the Calendar class whether I like it or not.
回答1:
Don't use Calendar use the java.time package instead:
import java.util.Scanner;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy");
LocalDate inputDate;
while(true){
System.out.print("Enter a date in the format of MM/dd/yyyy:");
String date = scanner.next();
try {
inputDate = LocalDate.parse(date, formatter);
break;
} catch (Exception e) {
System.err.println("ERROR: Please input the date in the correct format");
}
}
System.out.println("The day of week is " + inputDate.getDayOfWeek().name());
}
}
Example Usage:
Enter a date in the format of MM/dd/yyyy: 92/23/2344
ERROR: Please input the date in the correct format
Enter a date in the format of MM/dd/yyyy: 11/26/2019
The day of week is TUESDAY
However if you really need to use Calendar and want to use something resembling your existing code, try this:
N.B. Pay attention to the line formatter.setLenient(false);
which ensures strict parsing, such that input must match the EXACT format.
import java.util.Scanner;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.ParseException;
import java.util.Calendar;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
formatter.setLenient(false);
Date inputDate;
while(true){
System.out.print("Enter a date in the format of MM/dd/yyyy:");
String date = scanner.nextLine();
try {
inputDate = formatter.parse(date);
break;
} catch (Exception e) {
System.err.println("ERROR: Please input the date in the correct format");
}
}
Calendar c = Calendar.getInstance();
c.setTime(inputDate);
int dayOfWeek = c.get(Calendar.DAY_OF_WEEK);
String[] days = new String[] {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
System.out.println("The day of week is " + days[dayOfWeek - 1]);
}
}
Example Usage:
Enter a date in the format of MM/dd/yyyy: 92/23/2344
ERROR: Please input the date in the correct format
Enter a date in the format of MM/dd/yyyy: 11/26/2019
The day of week is Tuesday
回答2:
Minimize the use of outdated API
shash678’s answer is correct, also in recommending java.time
over the long outdated Calendar
class that you are required to use. I just wanted to add one point here: even though you are required to use the Calendar
class, it doesn’t necessarily imply you also need to use its outdated friends Date
and SimpleDateFormat
. The latter may be the most troublesome of them all and certainly one to avoid.
DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("M d u");
Scanner s = new Scanner(System.in);
System.out.println("Repeatedly enter a date (m d y) to get the day of week."
+ " Terminate input with a blank line.");
String date = s.nextLine();
LocalDate ld = LocalDate.parse(date, inputFormatter);
// the easy way to get day-of-week would be ld.getDayOfWeek(),
// but we are required to use Calendar
// (any ZoneId will do for atStartOfDay(), I just prefer to provide one)
Calendar c = GregorianCalendar.from(ld.atStartOfDay(ZoneOffset.UTC));
int numberOfDayOfWeek = c.get(Calendar.DAY_OF_WEEK);
// display
DayOfWeek dayOfWeek;
// Calendar’s dayOfWeek starts from 1 = Sunday;
// for DayOfWeek.of() we need to start from 1 = Monday
if (numberOfDayOfWeek == Calendar.SUNDAY) {
dayOfWeek = DayOfWeek.SUNDAY;
} else {
dayOfWeek = DayOfWeek.of(numberOfDayOfWeek - 1);
}
System.out.println("Day of week is "
+ dayOfWeek.getDisplayName(TextStyle.FULL_STANDALONE, Locale.US));
Sample session:
Repeatedly enter a date (m d y) to get the day of week. Terminate input with a blank line.
10 5 2017
Day of week is Thursday
I left out the repeat until an empty line is entered since you seem to be handling this fine already.
While the above is certainly not what your instructor was after, in real life the requirement to use a specific outdated class typically comes from using a legacy API that requires and/or gives you an instance of that old class. In such a case I recommend you minimize the use of the old API and use the modern one to the greatest extend possible. So in the code I convert to Calendar
only in the last moment before finding the day-of-week. Whether you convert from Date
to Calendar
or from LocalDate
to Calendar
doesn’t make any great difference to the complexity of the code, so you might as well do yourself the favor of using the modern LocalDate
.
I do add a little extra complexity by converting back from the int
from the Calendar
to the modern DayOfWeek
enum, which I use for displaying the day name. You can leave out this part if you want. I included it just to demonstrate that there is a way to avoid reinventing the wheel when converting from int
to day name.
来源:https://stackoverflow.com/questions/46554701/how-can-i-take-a-user-inputted-date-instead-of-the-current-date-in-the-calendar