所以我有这个方法,我想扩展以让用户输入有效的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)");
}
}
}
答案 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}可能更方便且面向对象}。