我有一个无法解决的问题。要求用户输入日期,并将其与今天的日期进行比较,如果是将来的日期,则要求用户再次输入日期。第一次它工作时,告诉用户它在未来,但当他输入有效日期时,它仍然显示为重新输入。感谢您的帮助。
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);
示例会话:
Purchase date DD/MM/YYYY:
15/3/2021
Re-enter
11/3/2021
You have successfully entered 2021-03-11
您的错误是:
- 您在格式化模式字符串中使用了错误的模式字母大小写。无论使用旧的麻烦的
SimpleDateFormat
还是现代的DateTimeFormatter
模式字母都是区分大小写的。大写D
表示年份,小写d
表示月份。大写Y
表示周-年,仅适用于周数。小写y
表示年份。在我的代码中,我使用小写u
来表示签名年份,这对于DateTimeFormatter
来说是特殊的 - 用户输入新日期时,您没有为
d2
分配新值。因此,当您的条件d2.compareTo(d) > 0
为真时,无论用户输入多少次不同的日期,它都将保持为真
您可以使用变量(例如下面代码中的boolean valid
(来跟踪输入是否有效。如果输入无效,则需要循环返回。对于这样的场景,我更喜欢使用dowhile循环,它保证至少执行一次它的主体。我还建议您处理无效输入的异常。
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 ...");
}
}
样本运行:
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 ...
请注意,java.util
日期时间API及其格式API、SimpleDateFormat
已过时且为错误产品。建议完全停止使用它们,并切换到现代日期时间API*。
使用现代日期时间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 ...");
}
}
从跟踪:日期时间了解有关现代日期时间API的更多信息。
注:
- 您错误地使用了
D
而不是d
。D
用于年中的天,而不是用于月中的天 - 您错误地使用了
Y
而不是y
。Y
用于周-年,而不是年
*出于任何原因,如果您必须坚持使用Java 6或Java 7,您可以使用ThreeTen Backport将Java.time的大部分功能向后移植到Java 6&7.如果您正在为Android项目工作,并且您的Android API级别仍然不符合Java-8,请检查通过desugaring和如何在Android项目中使用ThreeTenABP提供的Java 8+API