具有特殊模式的日期格式[重复]
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不支持日期可以是17th
、3rd
等的标准。
【问题讨论】:
对于您的输入字符串,只需运行四个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.由于这个答案只是关于删除序数后缀,甚至不显示日期格式模式,你为什么告诉我?在问题中说出来,或写下答案。
对不起,不是有意打扰。我已经在这个问题下发表了评论(并且已经关闭它,如你所见)。仍然认为我在这里的评论可能对您的答案的读者有所帮助,所以让它保持不变。以上是关于具有特殊模式的日期格式[重复]的主要内容,如果未能解决你的问题,请参考以下文章