This question already has answers here:
How to compare dates in Java? [duplicate]
(11 answers)
How to use Scanner to accept only valid int as input
(6 answers)
Java Date() giving the wrong date [duplicate]
(9 answers)
Java iterator.hasNext() is always true
(2 answers)
Closed 1 year ago.
I have problem which can't solve. The user is asked to input a date and it's compared to todays date and if it's in the future the user is asked to input date again. The first time it works and tells user it's in the future but when he enters a valid date it's still showing to re-enter. Any help appreciated.
System.out.println("Purchase date DD/MM/YYYY:");
String date = sc.nextLine();
SimpleDateFormat dateform = new SimpleDateFormat ("DD/MM/YYYY");
dateform.parse(date);
Date d = new Date();
Date d2 = dateform.parse(date);
while (d2.compareTo(d) > 0 ){
System.out.println("Re-enter");
date = sc.nextLine();
}
consumbles.add(date);
System.out.println("Purchase date DD/MM/YYYY:");
String date = sc.nextLine();
// Use java.time, the modern Java date and time API, for your date work.
// Use single letters in the format pattern string to allow user
// to enter single digit day and month.
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("d/M/u");
// Use saying variable names (not just d and d2)
LocalDate today = LocalDate.now(ZoneId.systemDefault());
LocalDate dateEntered = LocalDate.parse(date, dateFormatter);
// Using isAfter() for comparison is easier to read then compareTo()
while (dateEntered.isAfter(today)) {
System.out.println("Re-enter");
date = sc.nextLine();
// Parse the new entered date string into dateEntered
dateEntered = LocalDate.parse(date, dateFormatter);
}
System.out.println("You have successfully entered " + dateEntered);
Sample session:
Purchase date DD/MM/YYYY:
15/3/2021
Re-enter
11/3/2021
You have successfully entered 2021-03-11
Your errors were:
You were using the wrong case of pattern letters in your format pattern string. No matter if using the old and troublesome SimpleDateFormat or the modern DateTimeFormatter pattern letters are case sensitive. Upper case D is for day of year, lowercase d for day of month. Upper case Y is for week year and only useful with a week number. Lowercase y is for year of era. In my code I used lower case u for a signed year, this is special for DateTimeFormatter.
You were not assigning a new value to d2 when the user entered a new date. Thus when your condition, d2.compareTo(d) > 0, was true, it would stay true no matter how many times the user entered a different date.
You can use a variable (e.g. boolean valid in the code below) to track whether the input is valid. If the input is not valid, you need to loop back. I prefer using do-while loop, which guarantees to execute its body at least once, for such a scenario. I also recommend you handle exception for invalid input.
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws ParseException {
Scanner sc = new Scanner(System.in);
SimpleDateFormat parser = new SimpleDateFormat("d/M/yyyy", Locale.ENGLISH);
Date today = new Date();
boolean valid;
do {
valid = true;
System.out.print("Purchase date DD/MM/YYYY: ");
String strDate = sc.nextLine();
Date date = null;
try {
date = parser.parse(strDate);
if (date.after(today)) {
System.out.println("The date should not be a future date. Please try again.");
valid = false;
}
} catch (ParseException e) {
System.out.println("Invalid date/format. Please try again.");
valid = false;
}
} while (!valid);
System.out.println("Thank you! Processing ...");
}
}
A sample run:
Purchase date DD/MM/YYYY: a
Invalid date/format. Please try again.
Purchase date DD/MM/YYYY: 14/3/2021
The date should not be a future date. Please try again.
Purchase date DD/MM/YYYY: 12/2/2020
Thank you! Processing ...
Note that the java.util date-time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern date-time API*.
Using the modern date-time API:
import java.time.DateTimeException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
DateTimeFormatter parser = DateTimeFormatter.ofPattern("d/M/u", Locale.ENGLISH);
LocalDate today = LocalDate.now();
boolean valid;
do {
valid = true;
System.out.print("Purchase date DD/MM/YYYY: ");
String strDate = sc.nextLine();
LocalDate date = null;
try {
date = LocalDate.parse(strDate, parser);
if (date.isAfter(today)) {
System.out.println("The date should not be a future date. Please try again.");
valid = false;
}
} catch (DateTimeException e) {
System.out.println("Invalid date/format. Please try again.");
valid = false;
}
} while (!valid);
System.out.println("Thank you! Processing ...");
}
}
Learn more about the modern date-time API from Trail: Date Time.
Note:
You have wrongly used D instead of d. D is used for Day in year, not for Day in month.
You have wrongly used Y instead of y. Y is used for a Week year, not for year.
* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
Related
Could anybody please tell me why I'm getting "10/09/2022" on the console?
String sFecha = "10/21/2021";
try {
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
System.out.println(sdf.format(sdf.parse(sFecha)));
} catch (java.text.ParseException e) {
//Expected execution
}
Note: the input string is intentionally wrong - I am expecting the Exception!
java.time
The java.util Date-Time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern Date-Time API*.
The problem you have observed with your code is one of the weird problems that you face with SimpleDateFormat. Instead of throwing the exception because of the wrong format, SimpleDateFormat tries to parse the date string erroneously.
Solution using java.time, the modern Date-Time API:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
public class Main {
public static void main(String[] args) {
String sFecha = "10/21/2021";
try {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd/MM/yyyy");
LocalDate date = LocalDate.parse(sFecha, dtf);
System.out.println(date);
} catch (DateTimeParseException e) {
System.out.println("A problem occured while parsing the date string.");
// ...Handle the exception
}
}
}
Output:
A problem occured while parsing the date string.
Now, change the format to MM/dd/yyyy and you will see that the date string will be parsed successfully.
Learn more about the modern Date-Time API from Trail: Date Time.
In case you want to use SimpleDateFormat:
Pass false to SimpleDateFormat#setLenient which is set true by deafult.
Demo:
import java.text.SimpleDateFormat;
public class Main {
public static void main(String[] args) {
String sFecha = "10/21/2021";
try {
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
sdf.setLenient(false);
System.out.println(sdf.format(sdf.parse(sFecha)));
} catch (java.text.ParseException e) {
System.out.println("A problem occured while parsing the date string.");
// ...Handle the exception
}
}
}
Output:
A problem occured while parsing the date string.
* If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring. Note that Android 8.0 Oreo already provides support for java.time.
When you do sdf.parse() you convert your text to date with :
10 -> days
21 -> month
2021 -> year
And 21 as month is converted to 9 (because 21 % 12 = 9).
Using setLenient(false) it will throw an exception instead:
With lenient parsing, the parser may use heuristics to interpret inputs that do not precisely match this object's format. With strict parsing, inputs must match this object's format.
your format is day/month/year. 21 is not a valid month, It seems it subtracts 12 to get a valid one.
input list
from date ex) 2020-10-01
to date ex) 2020-10-30
List [day of week] ex) [sun,mon....]
List [week] ex) [1,4,5]
I would like to know how to get a specific day of the week between the two dates.
Thank.
from date ex) 2020-10-01 to date ex) 2020-10-30
Your input string is already in the ISO8601 format for date and therefore it can be parsed without providing a DateTimeFormatter explicitly. In order to get the output string in a custom format (e.g. yyyy-MM-dd), you need to format the date object using DateTimeFormatter.
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
String inputStrDate = "2020-10-01";
LocalDate date = LocalDate.parse(inputStrDate);
String outputStrDate = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
System.out.println(outputStrDate);
}
}
Output:
2020-10-01
However, if your input is some other format, you will need to use DateTimeFormatter in order to parse it to a date object.
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
// Formatter for input string
DateTimeFormatter inputFormat = DateTimeFormatter.ofPattern("dd-MM-yyyy");
String inputStrDate = "10-01-2020";
LocalDate date = LocalDate.parse(inputStrDate, inputFormat);
// Formatter for output string
DateTimeFormatter outputFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String outputStrDate = date.format(outputFormat);
System.out.println(outputStrDate);
}
}
Output:
2020-10-01
Learn more about date-time API from Trail: Date Time.
for(LocalDate d = fromDate; !d.isAfter(toDate); d = d.plusDays(1)) { // 일정 시작 ~ 끝 loop
for (Integer wf : weekOfMonth) {
for (Integer df : dayOfWeek) {
offDay = d.with(fieldWeek, wf)
.with(fieldDay, df);
if (d.getMonth() == offDay.getMonth() && !offDays.contains(offDay)) {
offDays.add(offDay);
}
}
}
}
Sorry for asking the wrong question.
And thank you very much.
I've already made it, but I've studied your code.
java.time
I too recommend that you use java.time, the modern Java date and time API, for your date work. My shot is:
LocalDate fromDate = LocalDate.of(2020, Month.OCTOBER, 1);
LocalDate toDate = LocalDate.of(2020, Month.OCTOBER, 30);
List<DayOfWeek> daysOfWeek = List.of(DayOfWeek.SUNDAY, DayOfWeek.MONDAY);
List<Integer> weeks = List.of(1, 4, 5);
if (! YearMonth.from(fromDate).equals(YearMonth.from(toDate))) {
throw new IllegalStateException("Covering more than one month is not yet supported");
}
WeekFields wf = WeekFields.SUNDAY_START;
for (int week : weeks) {
for (DayOfWeek dow : daysOfWeek) {
LocalDate date = fromDate.with(wf.weekOfMonth(), week)
.with(wf.dayOfWeek(), dow.get(wf.dayOfWeek()));
// Is date inside interval?
if (! (date.isBefore(fromDate) || date.isAfter(toDate))) {
System.out.println(date);
}
}
}
Output:
2020-10-18
2020-10-19
2020-10-25
2020-10-26
The dates printed are Sunday and Monday of weeks 4 and 5 of October defining weeks in the American way where the week begins on Sunday (since you mentioned Sunday first in your example list) and week 1 is the week of October 1. Sunday and Monday of week 1 are not printed because they fall before October 1, that is, in September.
Consider which week scheme you require. You may use for example WeekFields.ISO or WeekFields.of(Locale.getDefault()).
I am finding the week first, then the day of week, because to me this is the natural way. I need to use the WeekFields object for both adjustments to make sure that the chosen week scheme is respected.
If you need to cover more than one calendar month, iterate over the months and do the same for each. Also check that the result date falls within the month so duplicates near month borders are ignored.
I want to give an error message if the user inputs using the wrong format. The correct format is "yyyy-MM-dd HH:mm:ss". How can I put that as a condition?
for example
if (yyyy <0 )
{ sout("please input correct year")}
this is the code i use for ask the user and formatting it
Scanner keyboard = new Scanner(System.in);
String hour = "00:00:00";
System.out.println("Please enter Date : ");
String time = keyboard.next()+" "+ hour;
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime dateTime = LocalDateTime.parse(time, formatter);
You can use a regex comparison:
while input doesn't match the regex pattern
print "Please enter date in the correct format: yyyy-MM-dd HH:mm:ss"
continue with the rest of the code
The RegEx pattern could be:
\d{4}-[01]\d-[0-3]\d [0-2]\d:[0-5]\d:[0-5]\d(?:.\d+)?Z?
You can use this site to create and test RegEx patterns
If the user should just enter a date (such as 2019-03-31), there is no reason why your program should be concerned with time of day too. Furthermore, your format is ISO 8601, the format that LocalDate and the other the classes of java.time parse (and also print) as their default. So you don’t need an explicit formatter.
I understand that you want a range check, which is certainly advisable. In addition, if a user enters a completely different format, parsing will throw a DateTimeParseException which you should catch and act accordingly. For example:
LocalDate minAcceptedDate = LocalDate.of(0, Month.JANUARY, 1);
LocalDate maxAcceptedDate = LocalDate.of(4000, Month.DECEMBER, 31);
Scanner keyboard = new Scanner(System.in);
System.out.println("Please enter Date : ");
while (true) {
String time = keyboard.next();
try {
LocalDate dateTime = LocalDate.parse(time);
if (dateTime.isBefore(minAcceptedDate) || dateTime.isAfter(maxAcceptedDate)) {
System.out.println("Please enter a date in the range " + minAcceptedDate + " through " + maxAcceptedDate);
} else { // OK
break;
}
} catch (DateTimeParseException dtpe) {
System.out.println("Please enter a date in format yyyy-mm-dd");
}
}
Example session:
Please enter Date :
Yesterday
Please enter a date in format yyyy-mm-dd
-001-12-30
Please enter a date in format yyyy-mm-dd
5000-12-12
Please enter a date in the range 0000-01-01 through 4000-12-31
2016-09-22
I have a class DayOfWeek which takes a date from the user and prints the day of the week on that date.
For example the user will enter his date as: (with the format MM DD YYYY)
07 22 2016
and the output should be
FRIDAY
This is my class:
public class DayOfWeek{
public static void main(String[] args){
System.out.println("Enter the date (Format: MM DD YYYY) :");
Scanner sc = new Scanner(System.in);
String month = sc.next();
String day = sc.next();
String year = sc.next();
int m = Integer.parseInt(month);
int d = Integer.parseInt(day);
int y = Integer.parseInt(year);
Calendar cal = Calendar.getInstance();
Date date = new Date(y, m, d);
cal.setTime(date);
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
SimpleDateFormat sdf = new SimpleDateFormat("EEEE");
System.out.println((sdf.format(dayOfWeek)).toUpperCase());
}
}
However when I enter the date stated above (07 22 2016), I don't get the required output (FRIDAY). Instead the output is the current day of week on my system. I am totally stuck on what the problem is.
You're currently passing an int to SimpleDateFormat... you should pass the Date value. You don't need a Calendar at all for that:
// BAD CODE: DON'T USE - KEEP READING
import java.text.*;
import java.util.*;
public class DayOfWeek {
public static void main(String[] args){
System.out.println("Enter the date (Format: MM DD YYYY) :");
Scanner sc = new Scanner(System.in);
String month = sc.next();
String day = sc.next();
String year = sc.next();
int m = Integer.parseInt(month);
int d = Integer.parseInt(day);
int y = Integer.parseInt(year);
// Note the changes here
Date date = new Date(y - 1900, m - 1, d);
SimpleDateFormat sdf = new SimpleDateFormat("EEEE");
System.out.println(sdf.format(date).toUpperCase());
}
}
I've put the warning there because you're using a deprecated Date constructor - and it's deprecated for good reasons. Basically, java.util.Date is a terrible API and you should avoid using it if you possibly can. Your original call to new Date(y, m, d) was broken because the first parameter to java.util.Date(int, int, int) represents the year with a 1900 base (so a value of 117 means year 2017) and the second parameter represents the month with a 0 base (so a value of 6 means July). Then there's the implicit time zone conversion, which you really don't want.
You'd be much better off using java.time, and in this case the LocalDate class:
import java.time.*;
import java.time.format.*;
import java.util.*;
public class DayOfWeek {
public static void main(String[] args){
System.out.println("Enter the date (Format: MM DD YYYY) :");
Scanner sc = new Scanner(System.in);
String month = sc.next();
String day = sc.next();
String year = sc.next();
int m = Integer.parseInt(month);
int d = Integer.parseInt(day);
int y = Integer.parseInt(year);
LocalDate date = LocalDate.of(y, m, d);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEEE");
System.out.println(formatter.format(date).toUpperCase());
}
}
Finally, your approach to parsing the user input isn't ideal either - I'd suggest using a DateTimeFormatter for that, too:
import java.time.*;
import java.time.format.*;
public class DayOfWeek {
public static void main(String[] args){
System.out.println("Enter the date (Format: MM DD YYYY) :");
DateTimeFormatter parser = DateTimeFormatter.ofPattern("MM dd yyyy");
Scanner sc = new Scanner(System.in);
String line = sc.nextLine();
LocalDate date = LocalDate.parse(line, parser);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEEE");
System.out.println(formatter.format(date).toUpperCase());
}
}
Calendar c = Calendar.getInstance();
c.setTime(yourDate);
int dayOfWeek = c.get(Calendar.DAY_OF_WEEK);
if you need the output to be Tue rather than 3 (Days of week are indexed starting at (1), instead of going through a calendar, just reformat the string: new SimpleDateFormat("EE").format(date) (EE meaning "day of week, short version").
Note
As pointed by Jon Try and use the latest Date Time Formatter Api for this purpose the Date Api is depricated .
If you have your input as string, rather than Date, you should use SimpleDateFormat to parse it
: new SimpleDateFormat("dd/M/yyyy").parse(dateString)
#JonSkeet's answer is correct and already explains all the problems of the old API and how to use the new one. I'd just like to add another approach with java.time classes.
If you want just to get a String with the day of the week, you can skip the creation of a LocalDate and get directly a java.time.DayOfWeek.
The first part is the same (get the input from the Scanner and create a DateTimeFormatter to parse it).
Then I create a java.time.DayOfWeek from the parsed input, using the from method. So I call getDisplayName, using java.time.format.TextStyle (which is equivalent to EEEE format in #JonSkeet's answer) and a java.util.Locale to make it explicit that I want the day of week's names in English.
// read line from input
Scanner sc = new Scanner(System.in);
// get "07 22 2016" from the scanner
String line = sc.nextLine();
// formatter to parse the input
DateTimeFormatter parser = DateTimeFormatter.ofPattern("MM dd yyyy");
// get the day of the week
DayOfWeek dow = DayOfWeek.from(parser.parse(line));
// get day of week's name
String output = dow.getDisplayName(TextStyle.FULL, Locale.ENGLISH).toUpperCase();
The value of output variable will be FRIDAY - note that I also called toUpperCase(), because the result of getDisplayName is Friday.
The Locale is also important. If you don't specify a locale, it'll use the system's default, and it's not guaranteed to always be English. And it can also be changed without notice, even at runtime, so it's better to make it explicit in your code.
Notes:
The code above will also work if you want to change the language (just use a different Locale). But if you always want an English uppercase name, you can optionally call dow.toString(), which will also return FRIDAY as well.
This code focus only on the day of the week. If you need to use the date for other things than getting FRIDAY (like checking the day, month, etc), then you'll need a LocalDate and #JonSkeet's solution is preferred (and LocalDate has the method getDayOfWeek(), which returns the corresponding DayOfWeek, just in case you need it).
java.time is available only in Java >= 8. If you're using Java <= 7, though, you can use the ThreeTen Backport. The only difference is the package name (org.threeten.bp instead of java.time), but the classes and methods names are the same.
I realize this has been asked a lot. I did actually look. I've spent hours looking around and trying to figure this out. I'm supposed to be making a program that stores what amounts to a list of appointments in a database, with a description, date, start time, and end time. It has to take input from the user to add or cancel appointments, so as far as I know that means I need to convert a string to a date.
These are my imports:
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Time;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Scanner;
As you can see, no java.util.Date there. Here is the bit where I'm getting the error:
private static java.sql.Date getDay()
{
Scanner in = new Scanner(System.in);
String input;
Date apptDay = null;
DateFormat df = new SimpleDateFormat("yyyy/MM/dd");
java.sql.Date sqlDate;
System.out.println("\nPlease enter the date of the appointment, format: yyyy/mm/dd");
while(apptDay == null)
{
try
{
input = in.next();
apptDay = (Date) df.parse(input);
}
catch(ParseException e)
{
System.out.println("Please enter a valid date! Format is yyyy/mm/dd");
}
}
sqlDate = new Date(apptDay.getTime());
return sqlDate;
}
I've added java.sql.Dates to it and mucked about with it a bunch trying to get it to work, but it's still giving me this:
Exception in thread "main" java.lang.ClassCastException: java.util.Date cannot be cast to java.sql.Date
at Calendar.getDay(Calendar.java:47)
Any ideas on what I'm doing wrong or how to make this work would be very much appreciated.
Edit: I thought perhaps it would help if I added the bit of code that is calling this so maybe it will be more clear how I am trying to use it, so here is the addAppointment() method, so you can see where getDay() is being called and where it's going.
public static void addAppointment() throws SQLException
{
//get the info
String desc = getDesc();
java.sql.Date apptDay = getDay();
Time[] times = getTime();
Time startTime = times[0];
Time endTime = times[1];
int key;
Connection conn = SimpleDataSource.getConnection(); //connect to the database
try
{
PreparedStatement max = conn.prepareStatement("SELECT MAX(ID) FROM Calendar");
ResultSet result = max.executeQuery();
key = result.getInt("ID") + 1;
PreparedStatement stat = conn.prepareStatement(
"INSERT INTO Calendar " +
"VALUES (?, ?, ?, ?, ?)");
stat.setInt(1, key);
stat.setString(2, desc);
stat.setDate(3, apptDay);
stat.setTime(4, startTime);
stat.setTime(5, endTime);
stat.execute();
System.out.println("\nAppointment added!\n");
}
finally
{
conn.close(); //finished with the database
}
}
It would be much simpler to change the input format to yyyy-MM-dd and use java.sql.Date.valueOf(String date) method which converts a string in the above format to a java.sql.Date value directly.
This should work:
private static java.sql.Date getDay()
{
Scanner in = new Scanner(System.in);
String input;
Date apptDay = null;
DateFormat df = new SimpleDateFormat("yyyy/MM/dd");
java.sql.Date sqlDate;
System.out.println("\nPlease enter the date of the appointment, format: yyyy/mm/dd");
while(apptDay == null)
{
try
{
input = in.next();
apptDay = (Date) df.parse(input);
}
catch(ParseException e)
{
System.out.println("Please enter a valid date! Format is yyyy/mm/dd");
}
}
sqlDate = new java.sql.Date(apptDay.getTime());
return sqlDate;
}
java.sql.Date and java.util.Date are two different Classes. You need to convert the sql date into util date which is compatible with Calendar.
Date jDate = new Date(sqlDate.getTime());
and vice-versa
java.sql.Date sqlDate = new java.sql.Date(jDate.getTime());
The following statement caused the error:
apptDay = (java.sql.Date) df.parse(input);
In fact, the type of the return value of java.text.DateFormat.parse(String) is java.util.Date, which is incomparable with java.sql.Date.
In your situation, the easiest way might be using java.util.Date instead of java.sql.Date.
Another note: your class name Calendar is duplicate with java.util.Calendar. And it is not a good coding style to use class names which are already used by the standard library.
sqlDate = new java.sql.Date(apptDay.getTime());
Date.valueOf(scanner.nextLine())
String strDate = scanner.nextLine();
SimpleDateFormat format= new SimpleDateFormat("yyyy-MM-dd");
java.util.Date date = format.parse(strDate);
Try below method -
private static java.sql.Date getDay() throws SQLException {
Scanner in = new Scanner(System.in);
String input;
java.util.Date utilDay = null;
DateFormat df = new SimpleDateFormat("yyyy-mm-dd");
System.out.println("\nPlease enter the date of the appointment, format: yyyy-mm-dd");
while(utilDay == null){
try{
input = in.next();
utilDay = (java.util.Date) df.parse(input);
}catch(ParseException e){
System.out.println("Please enter a valid date! Format is yyyy/mm/dd");
}
}
java.sql.Date sqlDate = new java.sql.Date(utilDay.getTime());
return sqlDate;
}
And from main() method, call this method -
Date birthday = getDay();
java.time
It’s time someone writes the modern answer to this question.
Assuming that you are using (or can start using) a JDBC 4.2 compliant driver you should not use the two Date classes nor DateFormat or SimpleDateFormat. All those classes are poorly designed, the last two particularly troublesome. They are also long outdated. Instead rely on java.time, the modern Java date and time API. It’s much nicer to work with. We need a LocalDate and a DateTimeFormatter.
Now we’re at it, don’t use java.sql.Time either. Use LocalTime from java.time.
So your variable declarations become:
//get the info
String desc = getDesc();
LocalDate apptDay = getDay();
LocalTime[] times = getTime();
LocalTime startTime = times[0];
LocalTime endTime = times[1];
int key;
Only for passing the java.time objects to your prepared statement you don’t use setDate and setTime. You need to use setObject:
stat.setInt(1, key);
stat.setString(2, desc);
stat.setObject(3, apptDay);
stat.setObject(4, startTime);
stat.setObject(5, endTime);
stat.execute();
Everything else is as before. For parsing the user input string to a LocalDate, here is a short demonstration:
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy/M/d");
String input = "2019/11/09";
try {
LocalDate aptDate = LocalDate.parse(input, dateFormatter);
System.out.println("Parsed date: " + aptDate);
} catch (DateTimeParseException dtpe) {
System.out.println("Please enter a valid date. Format is yyyy/mm/dd");
}
The output from the last snippet is:
Parsed date: 2019-11-09
I have specified just one M and one d in the format pattern string to allow the user to enter one or two digits for month and day of month, for example 2019/11/9. Most users I know will appreciate this.
Link
Oracle tutorial: Date Time explaining how to use java.time.