簡體   English   中英

來自 LocalDate 和字符串的 Joda LocalDateTime

[英]Joda LocalDateTime from LocalDate and string

我有:

  • 一個 joda 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,可能還有另一種更簡單的方法

如何使用 Joda-Time 結合 LocalDate 和 String

您已經得到了詳細處理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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM