如何使用 Joda-Time 结合 LocalDate 和 String
您已经得到了详细处理Option 的使用的答案。在这里,我想更详细地介绍使用 Joda-Time 将您的 LocalDate 和您的 String 组合成 LocalDateTime。我了解您正在从旧代码中获取 Joda-Time LocalDate,并且需要将 Joda-Time LocalDateTime 返回到旧代码。我假设您知道时区的缩写在字符串中。我认为您应该验证该缩写,因为中欧时间在一年中的标准时间部分使用缩写 CET,在夏季时间 (DST) 使用 CEST。请原谅我的 Java 代码。
DateTimeUtils.setDefaultTimeZoneNames(createTimeZoneNamesMap());
DateTimeFormatter timeFormatter = DateTimeFormat.forPattern("H:mm z");
LocalDate date = new LocalDate(2021, 5, 22);
String timeAndZoneString = "14:20 CEST";
LocalTime time = LocalTime.parse(timeAndZoneString, timeFormatter);
DateTime dateTime = date.toDateTime(time, ZONE);
// Validate time zone abbreviation; take overlap at fall-back into account
String earlierCorrectTimeString = dateTime.withEarlierOffsetAtOverlap()
.toString(timeFormatter);
if (! timeAndZoneString.equals(earlierCorrectTimeString)) {
String laterCorrectTimeString = dateTime.withLaterOffsetAtOverlap()
.toString(timeFormatter);
if (! timeAndZoneString.equals(laterCorrectTimeString)) {
throw new IllegalStateException("Incorrect time zone abbreviation for date");
}
}
LocalDateTime ldt = dateTime.toLocalDateTime();
System.out.println(ldt);
输出:
2021-05-22T14:20:00.000
我使用了这两个辅助声明:
private static final DateTimeZone ZONE = DateTimeZone.forID("Europe/Paris");
private static Map<String, DateTimeZone> createTimeZoneNamesMap() {
Map<String, DateTimeZone> names = new HashMap<>(4);
names.put("CET", ZONE);
names.put("CEST", ZONE);
return names;
}
还验证了日期时间的有效性:date.toDateTime() 验证生成的 DateTime 不会落入 spring-forward 的间隙,如果会则抛出 IllegalInstantException:。
如果你在字符串中收到的小时数总是两位数,格式模式字符串需要指定这个,所以HH:mm z。
请注意,您在极端情况下会丢失信息:如果时间落在回退时的重叠中,则时区缩写会消除歧义,但您生成的 LocalDateTime 是不明确的。例如日期是2021-10-31,时间字符串是2:20 CEST。然后我们知道时间是在一年中的夏季时间,也就是在时钟倒转之前。您返回 2021-10-31T02:20:00.000,接收方将无法判断是将其理解为 2021-10-31T02:20:00.000+02:00(夏令时)还是 2021-10-31T02 :20:00.000+01:00(标准时间)。