具有特殊模式的日期格式[重复]

Posted

技术标签:

【中文标题】具有特殊模式的日期格式[重复]【英文标题】:Date formatting with special pattern [duplicate] 【发布时间】:2020-11-27 17:52:29 【问题描述】:

我输入了April 17th, 2024 之类的日期。日期是由谷歌语音转文本服务构建的。

要将此日期格式化为不同的格式,我将使用下一个代码:

        String input = "April 17th, 2024";
        DateTimeFormatter f = DateTimeFormatter.ofPattern( "MMM d, uuuu" )
                .withLocale( Locale.US );
        ZonedDateTime zdt = ZonedDateTime.parse( input , f );

        LocalDate ld = zdt.toLocalDate();
        DateTimeFormatter fLocalDate = DateTimeFormatter.ofPattern( "dd/MM/uuuu" );
        String output = ld.format( fLocalDate);
        System.out.println(output);

...问题是输入日期应该是April 17, 2024 或者模式必须改进。

非常严格的解决办法是把数字后面的字母删掉。

我宁愿避免添加额外的逻辑并改进输入数据的日期模式。 正是这一步我需要帮助(我在java doc 中找不到正确的解决方案)。

所以我希望得到格式化程序的更正或确认,java不支持日期可以是17th3rd等的标准。

【问题讨论】:

对于您的输入字符串,只需运行四个 replace 调用,删除“st”、“nd”、“rd”、“th”,这真的会更容易。为了安全起见,您可以使用逗号。 我知道在链接的原始问题中询问了麻烦且过时的SimpleDateFormat,但my answer here 使用DateTimeFormatter 和java.time,现代Java 日期和时间API。跨度> 其他几个问题:(1) 你需要MMMM 来获取完整的月份名称。 MMM 是月份的缩写,例如 Apr。 (2) 当字符串既不包含时间也不包含时区时,您不能解析成ZonedDateTime。解析成LocalDate 谢谢大家。我认为这个问题是重复的,最好的答案是here 感谢您的反馈。我不敢苟同。您已经在使用 java.time,这是现代 Java 日期和时间 API。您正在链接到一个使用臭名昭著的麻烦且早已过时的SimpleDateFormat 类和其他设计不佳的日期时间类的答案。这是一个巨大的倒退。这绝不是最好的答案。 【参考方案1】:

java.time 似乎不支持序数。

我能想到的“模式解决方案”是使用可选部分(即[] 之间的字符):MMMM d['th']['st']['nd']['rd'], yyyy

例如:

jshell> var fmt = DateTimeFormatter.ofPattern("MMMM d['th']['st']['nd']['rd'], yyyy").withLocale(Locale.US)
fmt ==> Text(MonthOfYear)' 'Value(DayOfMonth)['th']['st'] ... earOfEra,4,19,EXCEEDS_PAD)

jshell> LocalDate.parse("April 17th, 2024", fmt)
$63 ==> 2024-04-17

jshell> LocalDate.parse("April 1st, 2024", fmt)
$64 ==> 2024-04-01

jshell> LocalDate.parse("April 3rd, 2024", fmt)
$65 ==> 2024-04-03

jshell> LocalDate.parse("April 4, 2024", fmt)
$66 ==> 2024-04-04

它会拒绝其他字符:

jshell> LocalDate.parse("April 1fo, 2024", fmt)
|  Exception java.time.format.DateTimeParseException: Text 'April 1fo, 2024' could not be parsed at index 7
|        at DateTimeFormatter.parseResolved0 (DateTimeFormatter.java:2046)
|        at DateTimeFormatter.parse (DateTimeFormatter.java:1948)
|        at LocalDate.parse (LocalDate.java:428)
|        at (#68:1)

jshell> LocalDate.parse("April 1baar, 2024", fmt)
|  Exception java.time.format.DateTimeParseException: Text 'April 1baar, 2024' could not be parsed at index 7
|        at DateTimeFormatter.parseResolved0 (DateTimeFormatter.java:2046)
|        at DateTimeFormatter.parse (DateTimeFormatter.java:1948)
|        at LocalDate.parse (LocalDate.java:428)
|        at (#69:1)

但它会接受例如April 1th, 2024,即使不完全正确:

jshell> LocalDate.parse("April 1th, 2024", fmt)
$67 ==> 2024-04-01

它也会接受January 3thstndrd, 2024。不知道会不会有问题:

jshell> LocalDate.parse("January 3thstndrd, 2024", fmt)
$97 ==> 2024-01-03

【讨论】:

【参考方案2】:

Java 的日期格式化程序/解析器不支持 ordinal numbers。

你喜欢什么并不重要,你必须在调用解析器之前自己删除序数后缀。

真的没那么糟糕,例如

ZonedDateTime zdt = ZonedDateTime.parse( input.replaceFirst("(?:st|nd|rd|th),", ",") , f );

【讨论】:

不完美。您需要 MMMM 来获取完整的月份名称,例如 April。如果没有时间和时区,您将无法解析为 ZonedDateTime。试试LocalDate.parse( input.replaceFirst("(?:st|nd|rd|th),", ",") , f ) @OleV.V.由于这个答案只是关于删除序数后缀,甚至不显示日期格式模式,你为什么告诉我?在问题中说出来,或写下答案。 对不起,不是有意打扰。我已经在这个问题下发表了评论(并且已经关闭它,如你所见)。仍然认为我在这里的评论可能对您的答案的读者有所帮助,所以让它保持不变。

以上是关于具有特殊模式的日期格式[重复]的主要内容,如果未能解决你的问题,请参考以下文章

需要当前日期在具有日期格式的“UTC”时区[重复]

无法从 JavaScript 中的 JSON 文件获取具有日期格式的对象 [重复]

具有特定格式的日期,例如 YY-MM-DD [重复]

设置 PHP 日期时间格式

如何使用php将日期格式转换为日期时间格式[重复]

使用不带特殊字符 + 验证格式的日期输入创建一个 from