如何从字符串中解析时间(小时、分钟)?



>有人知道如何从看起来像"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,并进行了非常详尽的解释。

相关内容

  • 没有找到相关文章

最新更新