【问题标题】:How to parse a 1 or 2 digit hour string with Java?如何使用 Java 解析 1 或 2 位数的小时字符串?
【发布时间】:2020-05-15 13:28:44
【问题描述】:

我的解析器可能会遇到“2:37PM”(由“H:mma”解析)或“02:37PM”(由“hh:mma”解析)。我如何在不使用 try-catch 的情况下解析两者?

当我弄错时,我会收到这样的错误:

发现冲突:字段 AmPmOfDay 0 与派生的 AmPmOfDay 1 不同 从 02:37 开始

【问题讨论】:

  • 显示您使用的代码可能是个好主意,因为只有一个小的描述和无上下文的错误消息不是minimal reproducible example
  • 了解这些模式字母的确切含义可能也是一个好主意:错误很可能是由于 "2:37PM" 使用带有大写 H 加的模式进行解析一个一个。如果你使用大写的H,你就不需要在模式中使用那个a。用"h:mma" 解析第一个而不是"H:mma" 或将a 留在末尾,这会将其解析为"14:37"!
  • 这能回答你的问题吗? Problem with parse a LocalDateTime using java 8 和/或 this?

标签: java datetime time-format


【解决方案1】:

您确实说过要解析字符串。因此,您可以执行以下操作。

for (String s : new String[] { "02:37PM", "2:37PM" }) {
    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("h:mma");
    LocalTime lt = LocalTime.parse(s, dtf);
    System.out.println(lt.format(dtf));
}

打印

2:37PM
2:37PM

【讨论】:

    【解决方案2】:

    首先,您得到的错误是由您的模式中的 H 引起的,它以 24 小时格式解析小时,如果您在末尾添加 a(用于上午/下午),则会遇到麻烦模式。

    您可以使用java.timeStrings 解析为LocalTimes,使用考虑这两种模式的DateTimeFormatter

    public static void main(String[] args) {
        // define a formatter that considers two patterns
        DateTimeFormatter parser = DateTimeFormatter.ofPattern("[h:mma][hh:mma]");
        // provide example time strings
        String firstTime = "2:37PM";
        String secondTime = "02:37PM";
        // parse them both using the formatter defined above
        LocalTime firstLocalTime = LocalTime.parse(firstTime, parser);
        LocalTime secondLocalTime = LocalTime.parse(secondTime, parser);
        // print the results
        System.out.println("First:\t" + firstLocalTime.format(DateTimeFormatter.ISO_TIME));
        System.out.println("Second:\t" + secondLocalTime.format(DateTimeFormatter.ISO_TIME));
    }
    

    这个输出是

    First:  14:37:00
    Second: 14:37:00
    

    但事实证明,您只需要一种模式(无论如何,在DateTimeFormatter 中有两个模式要好于两个模式),因为h 能够解析一位或两位数的小时数。所以下面的代码产生的输出与上面的完全相同:

    public static void main(String[] args) {
        // define a formatter that considers hours consisting of one or two digits plus AM/PM
        DateTimeFormatter parser = DateTimeFormatter.ofPattern("h:mma");
        // provide example time strings
        String firstTime = "2:37PM";
        String secondTime = "02:37PM";
        // parse them both using the formatter defined above
        LocalTime firstLocalTime = LocalTime.parse(firstTime, parser);
        LocalTime secondLocalTime = LocalTime.parse(secondTime, parser);
        // print the results
        System.out.println("First:\t" + firstLocalTime.format(DateTimeFormatter.ISO_TIME));
        System.out.println("Second:\t" + secondLocalTime.format(DateTimeFormatter.ISO_TIME));
    }
    

    【讨论】:

    • 这是一个比我发现的“它有效”更有启发性的答案。谢谢!
    • @WebdevTory nice... 但请记住,您可以使用像这样定义的DateTimeFormatter 进行输出,但缺点是它会输出连接两种模式的时间。因此,如果您想输出它们或像我在本示例中所做的那样使用内置的,请为 LocalTime.format() 定义一个额外的。
    【解决方案3】:

    您可以为小时创建一个字符串,并使用 if 语句来检查小时是否

    【讨论】:

      【解决方案4】:

      您可以在字符串的小时部分使用带有 %02d 的 String#format。这将用 0 填充该值,直到其大小为 2。然后我们可以将原始小时部分替换为格式化部分。

              String timeLiteral = "2:37PM";
      
              String originalHour = timeLiteral.split(":")[0];
      
              String formattedHour = String.format("%02d", Integer.parseInt(originalHour));
      
              String result = timeLiteral.replace(originalHour, formattedHour);
      

      【讨论】:

        【解决方案5】:

        令我惊讶的是,答案似乎是格式化程序“h:mma”,它实际上可以正确识别一位数和两位数的小时规格,甚至可以捕捉到像“02:38 PM”这样的技术上可疑的时间(这可能应该没有前导 0,但告诉我的数据源...)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-11-04
          • 2012-05-25
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多