问题描述
我有无法解决的问题。要求用户输入日期并将其与今天的日期进行比较,如果是未来,则要求用户再次输入日期。它第一次工作并告诉用户它在将来,但是当他输入有效日期时,它仍然显示重新输入。任何帮助表示赞赏。
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
)来跟踪输入是否有效。如果输入无效,则需要循环返回。对于这种情况,我更喜欢使用 do-while loop,它保证至少执行一次其主体。我还建议您处理无效输入的异常。
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
已过时且容易出错。建议完全停止使用它们并切换到 modern date-time 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 ...");
}
}
从 Trail: Date Time 了解有关现代日期时间 API 的更多信息。
注意:
- 您错误地使用了
D
而不是d
。D
用于 Day in year,而不是用于月中的天。 - 您错误地使用了
Y
而不是y
。Y
用于 Week year,而不是 year。
* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 & 7. 如果您正在为 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaring 和 How to use ThreeTenABP in Android Project。