>有人知道如何从看起来像"01:20"-> 1:20AM 和"21:20" -> 9:20PM 的字符串中解析时间(小时、分钟和 AM/PM)吗?大多数解决方案似乎都假定或需要日期或日历对象。
我的输入时间实际上来自TimePickerDialog(特别是这个MaterialDateTimePicker实现,所以我只收到hourOfDay,分钟和秒(整数)。
我希望能够以友好的方式格式化用户选择的时间,即下午 12:30、凌晨 02:15 等。
我正在尝试使用乔达时间:
fun formattedTime(timeStr: String): String {
// Get time from date
val timeFormatter = DateTimeFormat.forPattern("h:mm a")
val displayTime = timeFormatter.parseLocalTime(timeStr)
return displayTime.toString()
}
但是我收到此错误,输入字符串例如"1:20":java.lang.IllegalArgumentException: Invalid format: "1:20" is too short
我也研究了SimpleDateFormat,但它似乎需要一个完整的日期时间字符串,例如在这个相关问题中
正如@ole-v-v指出的那样,SimpleDateFormat
已经看到了更好的日子 - 所以今天你可以使用java.time包来完成这项工作:
java.time.format.DateTimeFormatter target2 =
java.time.format.DateTimeFormatter.ofPattern("h:mm a");
java.time.format.DateTimeFormatter source2 =
java.time.format.DateTimeFormatter.ofPattern("HH:mm");
System.out.println("01:30 -> " + target2.format(source2.parse("01:30")));
System.out.println("21:20 -> " + target2.format(source2.parse("21:20")));
产生的结果
01:30 -> 1:30 AM
21:20 -> 9:20 PM
不出所料。
在Joda-Time中,你会按照@meno-hochschild在下面的回答中指出的那样编码。
使用SimpleDateFormat
它将如下所示:
SimpleDateFormat target = new SimpleDateFormat("h:mm a");
SimpleDateFormat source = new SimpleDateFormat("HH:mm");
System.out.println("01:30 -> " + target.format(source.parse("01:30")));
System.out.println("21:20 -> " + target.format(source.parse("21:20")));
这将从 24 小时时间解析为 12 小时显示
01:30 -> 1:30 AM
21:20 -> 9:20 PM
这完全取决于小时的格式 - 对于解析,您需要 24 小时(格式 HH),对于输出,您需要 12 小时加上 am/pm - 格式为 h。
如果您希望 01:30 成为 PM,则必须将其添加到要以某种方式解析的字符串中:
System.out.println("01:30 pm-> " + target.format(target.parse("01:30 pm")));
导致
01:30 pm-> 1:30 PM
接受的答案是正确的。然而,我很惊讶地看到像SimpleDateFormat
这样的旧类,尽管 OP 首先明确希望得到 Joda 答案(请参阅问题的标签)。所以我在这里发布乔达答案作为补充:
DateTimeFormatter target = DateTimeFormat.forPattern("h:mm a").withLocale(Locale.ENGLISH);
DateTimeFormatter source = DateTimeFormat.forPattern("HH:mm");
System.out.println("01:30 -> " + target.print(source.parseLocalTime("01:30")));
System.out.println("21:20 -> " + target.print(source.parseLocalTime("21:20")));
01:30 -> 1:30 上午
21:20 -> 9:20 下午
我建议不要混合两个不同的时间库(OP显然使用Joda-Time-Android)。
你的两个不错的选择是 Joda-Time 和java.time
.
由于您从时间选取器接收 hourOfDay、分钟和秒作为整数,因此无需执行任何分析。
java.time
DateTimeFormatter timeFormatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT)
.withLocale(Locale.US);
LocalTime time = LocalTime.of(hourOfDay, minute, second);
String displayTime = time.format(timeFormatter);
System.out.println(displayTime);
这将像这样打印时间:
下午11:45
我依赖于美国区域设置的内置本地化格式,而不是显式格式模式字符串。它在分钟和PM
(或AM
)之间放置了一个空格。我相信您的用户会对此感到高兴。如果没有,则需要改用DateTimeFormatter.ofPattern("h:mma", Locale.US)
。
乔达时间
如果您已经在使用 Joda-Time 并且此时没有理由进行更改,那么坚持下去是合理的。您可以使用LocalTime(int hourOfDay, int minuteOfHour, int secondOfMinute)
构造函数。然后按照Meno Hochschild的回答继续。这是一个很好的、知识渊博的答案。
请注意,Joda-Time被认为是一个基本上"完成"的项目。 没有计划进行重大改进。如果使用 Java SE 8,请迁移 到
java.time
(JSR-310)。
(引自Joda-Time主页)
远离简单日期格式
远离SimpleDateFormat
课。它可以为工作工作,但它不仅早已过时,而且众所周知很麻烦。
问:我可以在 Android 上使用 java.time 吗?
是的,java.time
在较旧和较新的Android设备上运行良好。它只需要至少Java6。
- 在Java 8及更高版本以及较新的Android设备上(我被告知从API级别26开始),现代API是内置的。
- 在Java 6和7中获取ThreeTen Backport,新类的反向移植(JSR 310的ThreeTen;请参阅底部的链接)。
- 在(较旧的)Android上使用Android版本的ThreeTen Backport。它被称为ThreeTenABP。并确保从带有子包的
org.threeten.bp
导入日期和时间类。
链接
- Oracle 教程:说明如何使用
java.time
的日期时间。 - Java 规范请求 (JSR) 310,其中首次描述了
java.time
。 - ThreeTen Backport 项目,将
java.time
向 Java 6 和 7 的反向移植(ThreeTen 用于 JSR-310)。 - ThreeTenABP,ThreeTen Backport 的安卓版
- 问:如何在Android项目中使用ThreeTenABP,并进行了非常详尽的解释。