[英]Joda LocalDateTime from LocalDate and string
我有:
LocalDate
,所以它沒有時間信息,只有日期"14:20 CEST"
它們中的任何一個都可以不存在(Scala 的Option
)。
如何將這兩者結合起來得到 joda LocalDateTime
,即僅代表日期和時間而沒有時區的實體?
要結合這兩個選項,自然的方法是使用這樣的flatMap
方法:
val onlyDateOption: Option[LocalDate] = ???
val timeAndZoneOption: Option[String] = ???
val result: Option[LocalDateTime] = onlyDateOption.flatMap { onlyDate =>
timeAndZoneOption.map { timeAndZone =>
// Some logic here to build the LocalDateTime from onlyDate and timeAndZone
}
}
也可以用更易讀的方式寫成for-comprehension
:
val result: Option[LocalDateTime] = for {
onlyDate <- onlyDateOption
timeAndZone <- timeAndZoneOption
} yield {
// Some logic here to build the LocalDateTime from onlyDate and timeAndZone
}
現在,如何使用 Joda 來構建您所期望的可能可以通過各種不同的方式完成,其中一種可能是:
onlyDate
.toLocalDateTime(LocalTime.MIDNIGHT)
.withHourOfDay(...) // hour extracted from the string somehow
.withMinuteOfHour(...) // minute extracted from the string somehow
我不熟悉Joda API,可能還有另一種更簡單的方法
您已經得到了詳細處理Option
使用的答案。 在這里,我想 go 更詳細地使用 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);
Output:
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(標准時間)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.