再次询问用户输入日期是否在未来

问题描述

我有无法解决的问题。要求用户输入日期并将其与今天的日期进行比较,如果是未来,则要求用户再次输入日期。它第一次工作并告诉用户它在将来,但是当他输入有效日期时,它仍然显示重新输入。任何帮助表示赞赏。

    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 的更多信息。

注意:

  1. 您错误地使用了 D 而不是 dD 用于 Day in year,而不是用于月中的天
  2. 您错误地使用了 Y 而不是 yY 用于 Week year,而不是 year

* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 & 7. 如果您正在为 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project