黑客
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,July和May)以及长月份名称的三个字母缩写(例如 , Feb)Dec,我使用[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.
- 也提供格式化的语言环境。