问题
My parser may encounter "2:37PM" (parsed by "H:mma") or "02:37PM" (parsed by "hh:mma"). How can I parse both without resorting to a try-catch?
I receive an error like this when I get it wrong:
Conflict found: Field AmPmOfDay 0 differs from AmPmOfDay 1 derived from 02:37
回答1:
First of all, the error you get is caused by the H
in your pattern, which parses hours in 24-hour format and gets into trouble if you put an a
(for AM/PM) at the end of the pattern.
You can use java.time
to parse the String
s to LocalTime
s using a DateTimeFormatter
that considers both of the patterns:
public static void main(String[] args) {
// define a formatter that considers two patterns
DateTimeFormatter parser = DateTimeFormatter.ofPattern("[h:mma][hh:mma]");
// provide example time strings
String firstTime = "2:37PM";
String secondTime = "02:37PM";
// parse them both using the formatter defined above
LocalTime firstLocalTime = LocalTime.parse(firstTime, parser);
LocalTime secondLocalTime = LocalTime.parse(secondTime, parser);
// print the results
System.out.println("First:\t" + firstLocalTime.format(DateTimeFormatter.ISO_TIME));
System.out.println("Second:\t" + secondLocalTime.format(DateTimeFormatter.ISO_TIME));
}
The output of this is
First: 14:37:00
Second: 14:37:00
But it turned out you only need one pattern (which is better to have than two in a DateTimeFormatter
anyway) because the h
is able to parse hours of one or two digits. So the following code produces exactly the same output as the one above:
public static void main(String[] args) {
// define a formatter that considers hours consisting of one or two digits plus AM/PM
DateTimeFormatter parser = DateTimeFormatter.ofPattern("h:mma");
// provide example time strings
String firstTime = "2:37PM";
String secondTime = "02:37PM";
// parse them both using the formatter defined above
LocalTime firstLocalTime = LocalTime.parse(firstTime, parser);
LocalTime secondLocalTime = LocalTime.parse(secondTime, parser);
// print the results
System.out.println("First:\t" + firstLocalTime.format(DateTimeFormatter.ISO_TIME));
System.out.println("Second:\t" + secondLocalTime.format(DateTimeFormatter.ISO_TIME));
}
回答2:
You did say you wanted to parse the string. So you can do the following.
for (String s : new String[] { "02:37PM", "2:37PM" }) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("h:mma");
LocalTime lt = LocalTime.parse(s, dtf);
System.out.println(lt.format(dtf));
}
Prints
2:37PM
2:37PM
回答3:
You can create a string for the hours and have an if statement to check whether the hours is < 10 (single digit) then prepend "0".
回答4:
You can use String#format with %02d on the hour portion of the String. This will pad the value with 0 until its size 2. We can then replace the original hour portion with the formatted portion.
String timeLiteral = "2:37PM";
String originalHour = timeLiteral.split(":")[0];
String formattedHour = String.format("%02d", Integer.parseInt(originalHour));
String result = timeLiteral.replace(originalHour, formattedHour);
回答5:
To my surprise, it looks like the answer was formatter "h:mma", which actually discerns correctly between one- and two-digit hour specifications and even catches technically dubious times like "02:38 PM" (which should probably not have a leading 0, but tell it to my data sources...)
来源:https://stackoverflow.com/questions/61820460/how-to-parse-a-1-or-2-digit-hour-string-with-java