【问题标题】:Returning a ZonedDateTime always from a Java TemporalAccessor with missing fields总是从缺少字段的 Java TemporalAccessor 返回 ZonedDateTime
【发布时间】:2020-05-19 14:29:29
【问题描述】:

我有一个类可以解析(相当)各种各样的日期:

// imports omitted for brevity

public final class DateParser
{
    private static final String DATE_TIME_FORMAT_PATTERN 
            = "[h][hh][[:][.]mm][[ ]a][ v][ ][[EEEE ][E ][d][dd][/][-][LLLL][L][/][-][uuuu]]";

    private static final DateTimeFormatter formatter 
            = DateTimeFormatter.ofPattern(DATE_TIME_FORMAT_PATTERN).localizedBy(Locale.ENGLISH);

    public static ZonedDateTime parseDateTimeString(final String dateTimeString)
    {
        TemporalAccessor parsedString = formatter.parse(dateTimeString);

        ZonedDateTime returnable = ZonedDateTime.now();

        // Return a ZonedDateTime with sane defaults if some fields are missing from parsedString
    }
}

如果 parsedString 不是完整的ZonedDateTime,我想返回一个具有合理默认值的ZonedDateTime

  1. 例如,给方法的字符串是"5:45pm"成功解析);我希望 ZonedDateTime 在当前时区反映 今天 下午 5:45。当然,如果今天已经过了四分之一到六点,那么更先发制人的方法是反映下一天下午 5:45,但我想先实现这一点。

  2. 其他可能的输入只是星期几,例如,"Monday":这将返回一个ZonedDateTime,设置为当前日期之后的下一个星期一,即当地时间下午 12 点。

  3. 仅输入日期 "4/2/2020" 将返回设置为本地时区的 ZonedDateTime,即输入中的日期(2020 年 2 月 4 日),时间设置为下午 12 点。

我该怎么做呢?我目前有一些代码,它只包含很长的ifs 链:

if (parsedString.isSupported(ChronoField.YEAR))
{
    returnable = returnable.withYear(parsedString.get(ChronoField.YEAR));
}            
if (parsedString.isSupported(ChronoField.DAY_OF_MONTH))
{
    returnable = returnable.withMonth(parsedString.get(ChronoField.MONTH_OF_YEAR));
}
if (parsedString.isSupported(ChronoField.DAY_OF_MONTH)) 
{
    returnable = returnable.withDayOfMonth(parsedString.get(ChronoField.DAY_OF_MONTH));
}
// And so on.

但是,这只是修改了当前的日期时间组。我不确定如何实现(2)和(3)之类的东西。

此外,有可能构建 ZonedDateTimeparsedString,通过迭代其字段,不知何故?还是有其他方法可以实现整个解析思路?

谢谢大家。

【问题讨论】:

  • 我怀疑你只能用一个模式来做到这一点,但你当然可以使用new DateTimeFormatterBuilder().appendPattern(DATE_TIME_FORMAT_PATTERN);,然后在同一个构建器上重复调用parseDefaulting
  • @VGR,这正是我所需要的,它成功地工作了。再次表明阅读 Javadocs 很重要。您介意将其发布为答案,以便我将其标记为已解决并给您一些信任吗?谢谢!

标签: java datetime time


【解决方案1】:

我认为你不能只用一个模式来做到这一点,但你可以创建一个 DateTimeFormatterBuilder 并调用它的parseDefaulting 方法:

DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
builder.appendPattern(DATE_TIME_FORMAT_PATTERN);

ZonedDateTime defaults = ZonedDateTime.now();

builder.parseDefaulting(ChronoField.YEAR,
       defaults.getLong(ChronoField.YEAR));
builder.parseDefaulting(ChronoField.MONTH_OF_YEAR,
       defaults.getLong(ChronoField.MONTH_OF_YEAR));
builder.parseDefaulting(ChronoField.DAY_OF_MONTH,
       defaults.getLong(ChronoField.DAY_OF_MONTH));
// etc.

DateTimeFormatter formatter = builder.toFormatter();

ZonedDateTime returnable = ZonedDateTime.parse(dateTimeString, formatter);

【讨论】:

    猜你喜欢
    • 2019-04-16
    • 2014-06-29
    • 2011-12-30
    • 1970-01-01
    • 2017-01-26
    • 1970-01-01
    • 2016-06-26
    • 1970-01-01
    • 2021-09-26
    相关资源
    最近更新 更多