0

我以“5 月 12 日星期二”的格式从用户那里获得输入,我想将格式更改为:“Tue_12_May”。

月份的输入格式可以有 3/4 个字母,例如:MayJulyFeb等。月份的输出格式无关紧要。

到目前为止,我已经尝试了以下代码片段:

public static String dateFormatter(String dateWithSpace) {
    DateTimeFormatter formatter1 = new DateTimeFormatterBuilder().parseCaseInsensitive().appendPattern("EEE, dd LLL").toFormatter(Locale.ENGLISH);
    DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("E_d_M/L");
    LocalDate date = LocalDate.parse(dateWithSpace.trim(), formatter1);
    return date.format(formatter2);
}

我不断收到此错误:

java.time.format.DateTimeParseException:无法在索引 8 处解析文本“5 月 12 日星期二”

4

2 回答 2

3

黑客

    String dateWithSpace = "Tue, 12 May";
    DateTimeFormatter formatter1 = new DateTimeFormatterBuilder()
            .parseCaseInsensitive()
            .appendPattern("EEE, d [MMMM][MMM]")
            .toFormatter(Locale.ENGLISH);
    DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("E_d_MMMM", Locale.ENGLISH);
    TemporalAccessor parsed = formatter1.parse(dateWithSpace .trim());
    String formatted = formatter2.format(parsed);

    System.out.println(formatted);

输出:

Tue_12_May

这里的挑战是我们不能在LocalDate. 我们需要LocalDate一年。我们不能仅仅决定某个固定的年份,原因有两个:(1)无论我们决定什么都可能是错误的,因此会在我们的程序中引入错误,即使错误最初不会出现;(2)LocalDate如果我们没有运气选择 5 月 12 日是星期二的年份,我们会反对不正确的星期几。即使我们以某种方式强制它,它也不会打印Tue回来,而是我们选择的一年中正确的星期几。也没有任何其他类型可以在没有年份的情况下保留一周中的一天、一个月中的一天和一个月。

好的解决方案是找出哪一年是正确的。也许今年和明年轮流尝试,如果两者都不匹配则抛出异常?

同时,我的技巧不是决定任何具体类型,而只是使用未决定的TemporalAccessor接口。

编辑:要接受完整的短月份名称(June,JulyMay)以及长月份名称的三个字母缩写(例如 , FebDec,我使用[MMMM][MMM]:可选的完整月份名称,后跟可选的月份缩写。因此,其中一个将始终匹配,而另一个将被忽略。

其他输入输出示例:

Wed, 1 July  -> Wed_1_July
Thu, 27 Aug  -> Thu_27_August
Mon, 8 Feb   -> Mon_8_February

在你的代码上

我有一些意见,其中大部分是次要的:

  • 你不应该需要parseCaseInsensitive()你的示例字符串(也许你可能会得到其他字符串,我不知道)。
  • 编辑:要接受一个月中的一位数字,只需d在格式模式字符串中输入一位以进行解析。它仍然会接受两位数。进一步决定您是希望输出中始终使用两位数还是该月的前 9 天只需要一位数。
  • 首选格式模式进行解析MMM。用于当月份不是日期的一部分时(在某些语言中,对于使用何种形式的月份名称会有所不同)。LLLLLL
  • 对于格式也使用MMM月份缩写,而不是M/L.
  • 也提供格式化的语言环境。
于 2020-05-03T11:14:51.270 回答
0

你可以通过这种方式简单地做到这一点:

public static String dateFormatter(String dateWithSpace) {
    DateTimeFormatter formatter1 = new DateTimeFormatterBuilder()
                    .appendOptional(DateTimeFormatter.ofPattern("E, d LLLL"))
                    .appendOptional(DateTimeFormatter.ofPattern("E, d LLL"))
                    .toFormatter();
    DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("E_d_LLL");
    return formatter2.format(formatter1.parse(dateWithSpace));
}

在您的情况下,问题是您正在使用LocalDate,但缺少 的一个重要参数LocalDate,即年份。您可以参考LocalDate 文档

LocalDate 是一个不可变的日期时间对象,它表示一个日期,通常被视为年-月-日。也可以访问其他日期字段,例如一年中的某一天、一周中的某一天和一年中的一周。例如,值“2007 年 10 月 2 日”可以存储在 LocalDate 中。

于 2020-05-03T11:35:40.713 回答