SimpleDateFormat并且不允许它超过12小时

时间:2017-04-02 06:48:13

标签: java date time format simpledateformat

所以我有这个方法,我想扩展以让用户输入有效的12小时时间。而且我对它有这个工作正常。但我想要它,如果小时超过12小时或分钟超过59,那么它将提示再次进行。但是现在它只是通过添加它来转换时间。 还有更有效的方法来写这个吗? (就像没有了 日期newTime = sdf.parse(startTime); 并且拥有它以便用户可以只输入一个字符串并检查它是否格式正确?

public static void userInput(){
    Scanner in = new Scanner(System.in);
    SimpleDateFormat sdf = new SimpleDateFormat("hh:mm aa");
    String startTime;

    System.out.print("What is the start time?: ");
    boolean success = false;
    while (success != true){
        try{
        startTime = in.nextLine();
        Date newTime = sdf.parse(startTime);
        startTime = sdf.format(newTime);


        System.out.println(startTime);

        success = true;
        }
        catch(Exception e){
            System.out.println("Not a valid time. Please use this format (HH:MM AM)");
        }
    }
}

1 个答案:

答案 0 :(得分:0)

您遇到SimpleDateFormat按设计行事。这种行为对大多数人来说都是一个负面的惊喜。

有两种解决方案:推荐的解决方案和劝阻的解决方案。

推荐解决方案:LocalTime

        DateTimeFormatter timeFormat = DateTimeFormatter.ofPattern("hh:mm a", Locale.ROOT);
        try {
            LocalTime lt = LocalTime.parse(startTime, timeFormat);
            startTime = lt.format(timeFormat);
            System.out.println(startTime);
        } catch (DateTimeParseException e) {
            System.out.println("Not a valid time. Please use this format (HH:MM AM)");
        }
在Java 8中引入了

LocalTime以及其他一些设计更好且程序员更友好的类。如果你不能使用Java 8,那么还有两个解决方案:(1)诉诸气馁的解决方案,请参阅下面。 (2)使用Java 8日期和时间类的后端到Java 6和7:ThreeTen Backport(我没有使用ThreeTen Backport的经验)。

在代码中,请指定正确的区域设置而不是Locale.ROOT。我不知道AM和PM在某些语言环境中是否有其他名称,所以我想确保我们使用的语言环境与此时的用户输入一致。

气馁解决方案:setLenient()

    SimpleDateFormat sdf = new SimpleDateFormat("hh:mm aa");
    sdf.setLenient(false);

默认情况下SimpleDateFormat lenient ,并且在10:03和上午14:00作为02:00 PM接受09:63。当您setLenient(false)时,它将不再以这种方式接受超出范围的值,但会按预期抛出ParseException

只检查格式是否正确

在任一解决方案中,检查格式的最佳方法是您已经在做的事情:您尝试解析它并捕获相关的异常类型。只有抓住Exception才具体,因为异常可能来自许多其他原因。也就是说,使用推荐的解决方案捕获DateTimeParseException,使用不鼓励的解决方案捕获ParseException

此外,如果您想存储以后使用的时间,将它存储为LocalTime(或哪个类最能反映您的需求)而不是{{1}可能更方便且面向对象}。