要解析时间,可以按照@Jon Skeet's answer中的说明进行:
String input = "5:45 PM";
DateTimeFormatter parser = DateTimeFormatter.ofPattern("h:mm a", Locale.ENGLISH);
LocalTime time = LocalTime.parse(input, parser);
请注意,我还使用了java.util.Locale,因为如果您不指定它,它将使用系统的默认语言环境 - 并且某些语言环境可以为 AM/PM 字段使用不同的符号。使用显式语言环境可以避免这种极端情况(默认语言环境也可以更改,即使在运行时也是如此,因此最好使用显式语言环境)。
要结合今天的日期,您需要java.time.LocalDate(获取日期)并结合LocalTime,得到LocalDateTime:
// combine with today's date
LocalDateTime combined = LocalDate.now().atTime(time);
然后您可以使用另一个格式化程序格式化LocalDateTime:
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm");
System.out.println(combined.format(fmt));
输出是:
16/08/2017 17:45
如果要将LocalDateTime 转换为java.util.Date,则必须注意一些细节。
java.util.Date 表示自 1970-01-01T00:00Z(又名 Unix 纪元)以来的毫秒数。这是一个瞬间(一个特定的时间点)。更多信息请查看this article。
因此,同一个 Date 对象可以代表不同的日期或时间,具体取决于您所在的位置:想一想,此时此刻,世界上的每个人都处于同一瞬间(自1970-01-01T00:00Z),但世界各地的本地日期和时间不同。
LocalDateTime 代表“本地”概念:它是日期(日、月和年)和时间(小时、分钟、秒和纳秒),但与特定时区没有任何关系。
同一个LocalDateTime 对象可以代表不同时区的不同时刻。因此,要将其转换为 Date,您必须定义所需的时区。
一种选择是使用系统的默认时区:
// convert to system's default timezone
ZonedDateTime atDefaultTimezone = combined.atZone(ZoneId.systemDefault());
// convert to java.util.Date
Date date = Date.from(atDefaultTimezone.toInstant());
但默认值可能因系统/环境而异,也可以更改,即使在运行时也是如此。为了不依赖它并对其进行更多控制,您可以使用显式区域:
// convert to a specific timezone
ZonedDateTime zdt = combined.atZone(ZoneId.of("Europe/London"));
// convert to java.util.Date
Date date = Date.from(zdt.toInstant());
请注意,我使用了Europe/London。 API 使用IANA timezones names(始终采用Region/City 格式,如America/Sao_Paulo 或Europe/Berlin)。
避免使用三个字母的缩写(如CST 或PST),因为它们是ambiguous and not standard。
您可以致电ZoneId.getAvailableZoneIds() 获取可用时区列表(并选择最适合您系统的时区)。
还有夏令时的极端情况(LocalDateTime 可以存在两次,或者由于overlaps and gaps 而不能存在)。在这种情况下,Jon's solution 使用 ZonedDateTime 可以避免这个问题。