如何使用 Java 解析 1 位或 2 位数字的小时字符串?
How to parse a 1 or 2 digit hour string with Java?
我的解析器可能会遇到“2:37PM”(由 "H:mma" 解析)或“02:37PM”(由 "hh:mma" 解析)。如何在不求助于 try-catch 的情况下解析两者?
当我弄错时,我会收到这样的错误:
Conflict found: Field AmPmOfDay 0 differs from AmPmOfDay 1 derived
from 02:37
您可以为小时数创建一个字符串,并使用 if 语句检查小时数是否小于 10(个位数),然后在前面加上“0”。
您可以在字符串的小时部分使用 String#format 和 %02d。这将用 0 填充值直到其大小为 2。然后我们可以用格式化部分替换原始小时部分。
String timeLiteral = "2:37PM";
String originalHour = timeLiteral.split(":")[0];
String formattedHour = String.format("%02d", Integer.parseInt(originalHour));
String result = timeLiteral.replace(originalHour, formattedHour);
您确实说过要解析字符串。因此,您可以执行以下操作。
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));
}
版画
2:37PM
2:37PM
首先,你得到的错误是由你的模式中的 H
引起的,它以 24 小时格式解析小时,如果你把 a
(对于 AM/PM) 在模式的末尾。
您可以使用 java.time
将 String
解析为 LocalTime
,使用考虑了两种模式的 DateTimeFormatter
:
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));
}
这个的输出是
First: 14:37:00
Second: 14:37:00
但事实证明你只需要一个模式(无论如何在 DateTimeFormatter
中有两个模式更好)因为 h
能够解析一位或两位数的小时数。所以下面的代码产生与上面完全相同的输出:
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));
}
令我惊讶的是,答案似乎是格式化程序 "h:mma",它实际上正确区分了一位数和两位数的小时规范,甚至捕捉到了技术上可疑的时间,例如“02:38 PM”(可能不应该有前导 0,但告诉我的数据源...)
我的解析器可能会遇到“2:37PM”(由 "H:mma" 解析)或“02:37PM”(由 "hh:mma" 解析)。如何在不求助于 try-catch 的情况下解析两者?
当我弄错时,我会收到这样的错误:
Conflict found: Field AmPmOfDay 0 differs from AmPmOfDay 1 derived from 02:37
您可以为小时数创建一个字符串,并使用 if 语句检查小时数是否小于 10(个位数),然后在前面加上“0”。
您可以在字符串的小时部分使用 String#format 和 %02d。这将用 0 填充值直到其大小为 2。然后我们可以用格式化部分替换原始小时部分。
String timeLiteral = "2:37PM";
String originalHour = timeLiteral.split(":")[0];
String formattedHour = String.format("%02d", Integer.parseInt(originalHour));
String result = timeLiteral.replace(originalHour, formattedHour);
您确实说过要解析字符串。因此,您可以执行以下操作。
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));
}
版画
2:37PM
2:37PM
首先,你得到的错误是由你的模式中的 H
引起的,它以 24 小时格式解析小时,如果你把 a
(对于 AM/PM) 在模式的末尾。
您可以使用 java.time
将 String
解析为 LocalTime
,使用考虑了两种模式的 DateTimeFormatter
:
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));
}
这个的输出是
First: 14:37:00
Second: 14:37:00
但事实证明你只需要一个模式(无论如何在 DateTimeFormatter
中有两个模式更好)因为 h
能够解析一位或两位数的小时数。所以下面的代码产生与上面完全相同的输出:
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));
}
令我惊讶的是,答案似乎是格式化程序 "h:mma",它实际上正确区分了一位数和两位数的小时规范,甚至捕捉到了技术上可疑的时间,例如“02:38 PM”(可能不应该有前导 0,但告诉我的数据源...)