简体   繁体   English

来自 LocalDate 和字符串的 Joda LocalDateTime

[英]Joda LocalDateTime from LocalDate and string

I have:我有:

  • a joda LocalDate , so it has no time information and just date一个 joda LocalDate ,所以它没有时间信息,只有日期
  • a string which contains time and zone information, like "14:20 CEST"包含时间和区域信息的字符串,例如"14:20 CEST"

Either of them can be absent (Scala's Option ).它们中的任何一个都可以不存在(Scala 的Option )。

How can I combine these two to get joda LocalDateTime , ie entity representing only date and time with no timezone?如何将这两者结合起来得到 joda LocalDateTime ,即仅代表日期和时间而没有时区的实体?

To combine these 2 options, the natural way is to use flatMap method like this:要结合这两个选项,自然的方法是使用这样的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
  }
}

Which can also be written with for-comprehension in more readible way:也可以用更易读的方式写成for-comprehension

val result: Option[LocalDateTime] =  for {
  onlyDate <- onlyDateOption
  timeAndZone <- timeAndZoneOption
} yield { 
  // Some logic here to build the LocalDateTime from onlyDate and timeAndZone
}

Now, how to use Joda to build what you're expecting can probably be done in various different ways, one could be:现在,如何使用 Joda 来构建您所期望的可能可以通过各种不同的方式完成,其中一种可能是:

onlyDate
  .toLocalDateTime(LocalTime.MIDNIGHT)
  .withHourOfDay(...) // hour extracted from the string somehow
  .withMinuteOfHour(...) // minute extracted from the string somehow

I'm not familiar with Joda API, there is probably another easier way我不熟悉Joda API,可能还有另一种更简单的方法

How to combine LocalDate and String using Joda-Time如何使用 Joda-Time 结合 LocalDate 和 String

You have already got an answer treating the use of Option in detail.您已经得到了详细处理Option使用的答案。 Here I want to go into more detail with the combination of your LocalDate and your String into a LocalDateTime using Joda-Time.在这里,我想 go 更详细地使用 Joda-Time 将您的LocalDate和您的String组合成LocalDateTime I understand that you are getting a Joda-Time LocalDate from legacy code and need to return a Joda-Time LocalDateTime to legacy code.我了解您正在从旧代码中获取 Joda-Time LocalDate并且需要将 Joda-Time LocalDateTime返回到旧代码。 I am assuming that you know the time zone the abbreviation of which is in the string.我假设您知道时区的缩写在字符串中。 I think that you should validate that abbreviation since Central European Time uses the abbreviation CET during the standard time part of the year and CEST during summer time (DST).我认为您应该验证该缩写,因为中欧时间在一年中的标准时间部分使用缩写 CET,在夏季时间 (DST) 使用 CEST。 Excuse my Java code.请原谅我的 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: Output:

2021-05-22T14:20:00.000 2021-05-22T14:20:00.000

I have used these two auxiliary declaration:我使用了这两个辅助声明:

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;
}

The validity of the time on the date is also validated: date.toDateTime() validates that the resulting DateTime would not fall in the gap at the spring-forward and throws an IllegalInstantException: if it would.日期上时间的有效性也得到验证: date.toDateTime()验证生成的DateTime不会落入 spring-forward 的间隙并抛出IllegalInstantException:如果会。

If the hours you receive in the string are always two digits, the format pattern string needs to specify this, so HH:mm z .如果您在字符串中收到的小时数始终为两位数,则格式模式字符串需要指定这一点,因此HH:mm z

Please be aware that you are losing information in a corner case: If the time falls in the overlap at fall-back, the time zone abbreviation disambiguates, but the LocalDateTime that you produce is ambiguous.请注意,您在极端情况下会丢失信息:如果时间落在回退时的重叠中,则时区缩写会消除歧义,但您生成的LocalDateTime是不明确的。 For example the date is 2021-10-31 and the time string is 2:20 CEST .例如,日期是2021-10-31 ,时间字符串是2:20 CEST Then we know that the time is in the summer time part of the year, that is, before the clocks are turned back.然后我们知道时间是在一年中的夏季时间,也就是在时钟倒转之前。 You return 2021-10-31T02:20:00.000, and the receiver won't be able to tell whether to understand it as 2021-10-31T02:20:00.000+02:00 (summer time) or 2021-10-31T02:20:00.000+01:00 (standard time).您返回 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