首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >在Java中解析格式为“2010年1月10日”的日期?(使用序数指示符,st|nd|rd|th)

在Java中解析格式为“2010年1月10日”的日期?(使用序数指示符,st|nd|rd|th)
EN

Stack Overflow用户
提问于 2011-01-18 09:10:00
回答 4查看 5.4K关注 0票数 12

我需要在Java中解析“2010年1月10日”格式的日期。我该怎么做呢?

如何处理尾随日期数字的ordinal indicatorsstndrdth

EN

回答 4

Stack Overflow用户

发布于 2011-01-18 09:21:21

这是可行的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
String s = "January 10th, 2010";
DateFormat dateFormat = new SimpleDateFormat("MMM dd yyyy");
System.out.println("" + dateFormat.parse(s.replaceAll("(?:st|nd|rd|th),", "")));

但您需要确保使用正确的Locale来正确解析月份名称。

我知道您可以在SimpleDateFormat模式中包含常规文本。但是,在这种情况下,文本依赖于信息,实际上与解析过程无关。

这实际上是我能想到的最简单的解决方案。但我很乐意被人误导。

您可以通过执行类似以下操作来避免其中一条评论中暴露出的陷阱:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
String s = "January 10th, 2010";
DateFormat dateFormat = new SimpleDateFormat("MMM dd yyyy");
System.out.println("" + dateFormat.parse(s.replaceAll("(?<= \\d+)(?:st|nd|rd|th),(?= \\d+$)", "")));

例如,这将允许您不匹配Jath,uary 10 2010

票数 12
EN

Stack Overflow用户

发布于 2019-07-19 17:13:42

我想贡献一下现代的答案。您应该使用java.time,而不是现在投票最多的两个答案中使用的SimpleDateFormat类,它是现代Java date and time API。它提供了几个很好的解决方案。

简单的解决方案

我们首先定义一个用于解析的格式化程序:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private static final DateTimeFormatter PARSING_FORMATTER = DateTimeFormatter.ofPattern(
        "MMMM d['st']['nd']['rd']['th'], uuuu", Locale.ENGLISH);

然后我们像这样使用它:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    String dateString = "January 10th, 2010";
    LocalDate date = LocalDate.parse(dateString, PARSING_FORMATTER);
    System.out.println("Parsed date: " + date);

输出为:

解析日期: 2010-01-10

格式模式字符串中的方括号[]包含可选部分,单引号包含文字文本。因此,d['st']['nd']['rd']['th']意味着在月日之后可能会有stndrd和/或th

更可靠的解决方案

上面的方法有几个限制是

它接受任何序数指示符,例如,格式化程序用于解析的10st甚至10stndrdth.

  • While,您不能使用它进行格式化(它会给出January 10stndrdth, 2010).

如果您希望更好地验证序号指示符,或者希望将日期重新格式化为字符串,则可以按以下方式构建格式化程序:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private static final DateTimeFormatter FORMATTING_AND_PARSING_FORMATTER;
static {
    Map<Long, String> ordinalNumbers = new HashMap<>(42);
    ordinalNumbers.put(1L, "1st");
    ordinalNumbers.put(2L, "2nd");
    ordinalNumbers.put(3L, "3rd");
    ordinalNumbers.put(21L, "21st");
    ordinalNumbers.put(22L, "22nd");
    ordinalNumbers.put(23L, "23rd");
    ordinalNumbers.put(31L, "31st");
    for (long d = 1; d <= 31; d++) {
        ordinalNumbers.putIfAbsent(d, "" + d + "th");
    }

    FORMATTING_AND_PARSING_FORMATTER = new DateTimeFormatterBuilder()
            .appendPattern("MMMM ")
            .appendText(ChronoField.DAY_OF_MONTH, ordinalNumbers)
            .appendPattern(", uuuu")
            .toFormatter(Locale.ENGLISH);
}

这将解析与上面相同的日期字符串。让我们也尝试一下格式化:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    System.out.println("Formatted back using the same formatter: "
            + date.format(FORMATTING_AND_PARSING_FORMATTER));

使用相同的格式化程序重新格式化: 2010年1月10日

链接

票数 2
EN

Stack Overflow用户

发布于 2011-01-18 10:04:01

您可以将nd等设置为SimpleDateFormat中的文字。您可以定义四种所需的格式并尝试它们。首先从th开始,因为我猜这种情况会更经常发生。如果使用ParseException失败,请尝试下一个。如果所有操作都失败,则抛出ParseException。这里的代码只是一个概念。在现实生活中,您可能不会每次都生成新的格式,并且可能会考虑线程安全性。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public static Date hoolaHoop(final String dateText) throws ParseException
        {
        ParseException pe=null;
        String[] sss={"th","nd","rd","st"};
        for (String special:sss)
        {
        SimpleDateFormat sdf=new SimpleDateFormat("MMMM d'"+special+",' yyyy");
        
        try{
        return sdf.parse(dateText);
        }
        catch (ParseException e)
        {
        // remember for throwing later 
        pe=e;
        }
        }
        throw pe;
        }
        public static void main (String[] args) throws java.lang.Exception
        {
         String[] dateText={"January 10th, 2010","January 1st, 2010","January 2nd, 2010",""};
         for (String dt:dateText) {System.out.println(hoolaHoop(dt))};
        }

输出:

Sun Jan 10 00:00:00 GMT 2010

Fri 01 GMT 2010 00:00:00

星期六1月2日格林尼治时间2010 00:00:00

线程"main“java.text.ParseException中出现异常:无法分析日期:"”

当然,"th","nd","rd","st"只适用于使用英语的语言环境。请记住这一点。在法国,我猜是"re","nd"等等。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4722289

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文