【问题标题】:Date Format Issue With DateTimeFormatter [duplicate]DateTimeFormatter 的日期格式问题 [重复]
【发布时间】:2021-01-20 09:51:10
【问题描述】:

我的日期格式如下:1/1/2020 3:4:7 AM 我正在尝试使用DateTimeFormatter 对其进行格式化。

我有以下代码和格式化程序来解析它,但它不起作用。

LocalDateTime date = LocalDateTime.parse("1/1/2020 3:4:7 AM", DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss a"));

我得到以下异常:

java.time.format.DateTimeParseException: Text '1/1/2020 3:4:7 AM' could not be parsed at index 0

谁能帮帮我?

【问题讨论】:

  • 您是否尝试过使用"M/d/uuuu h:m:s a" 作为格式模式?

标签: java java-time localdatetime datetimeformatter


【解决方案1】:
  1. 对日期和时间部分(月、日、年、小时、分钟和秒)使用单个字母。

  2. 您还可以让格式化程序以不区分大小写的方式(例如 am、AM、Am)处理模式,如下所示:

    import java.time.LocalDateTime;
    import java.time.format.DateTimeFormatter;
    import java.time.format.DateTimeFormatterBuilder;
    import java.util.Locale;
    
    public class Main {
        public static void main(String[] args) {
             // Formatter to handle the pattern in case insensitive way (e.g. am, AM, Am)
            DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                                                .parseCaseInsensitive()
                                                .appendPattern("M/d/u h:m:s a")
                                                .toFormatter(Locale.ENGLISH);
            LocalDateTime date = LocalDateTime.parse("1/1/2020 3:4:7 AM", formatter);
            System.out.println(date);
        }
    }
    

输出:

2020-01-01T03:04:07

【讨论】:

  • 太好了,有人在这里介绍了DateTimeFormatterBuilder ;-)
【解决方案2】:

两个独立的问题:

计数错误

您正在使用例如MM 是一个明确的:总是完整的数字,零填充。你的字符串不是那样的,它只是数字。所以,把它变成M/d/uuuu h:m:s a

编辑:将yyyy 更改为uuuu,谢谢@deHaar。推理:yyyy 或 uuuu 很少重要,但请注意,这意味着 4 位数字是必需的。差异在 0 之前持续多年:uuuu 变为负数,yyyy 没有并希望您使用例如GG 以便您得到 44 BC 而不是 -44。这样一来,uuuu 就更正确了,尽管通常不会出现差异。

缺少语言环境

第二个问题是你应该永远不要使用这个版本的ofPattern - 它有一个错误,你无法通过单元测试来捕捉它,这使得它成为一个错误“重”数千倍,因此是一个真正的问题。

您需要指定语言环境。没有它,除非您的平台默认语言环境是英语,否则“AM”将无法解析。

把它放在一起

LocalDateTime date = LocalDateTime.parse("1/1/2020 3:4:7 AM",
  DateTimeFormatter.ofPattern("M/d/uuuu h:m:s a", Locale.ENGLISH));

效果很好。

【讨论】:

  • 谢谢,我将您的答案标记为已接受,因为您指出 Local.ENGLISH 也是必需的。
  • 我会使用uuuu 表示这一年(没有特定时代),否则这个答案得到了当之无愧的接受......
【解决方案3】:

根据documentation of DateTimeFormatter

数字:如果字母数为一个,则使用最小位数输出该值且不进行填充。否则,将使用位数作为输出字段的宽度,并根据需要将值补零。

通过颠倒推理,您可以尝试使用此格式化程序:

DateTimeFormatter.ofPattern("M/d/yyyy h:m:s a")

【讨论】:

    【解决方案4】:

    在你的 sn-p 中:

    LocalDateTime
        .parse("1/1/2020 3:4:7 AM", DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss a"));
    
    • 1 - 不匹配 MM
    • 1 - 不匹配 dd
    • 3 - 不匹配 hh
    • 4 - 不匹配 mm
    • 7 - 不匹配 ss

    格式化程序模式部分的长度(例如MM)和它们在字符串文本中的相应部分(例如1)不匹配。

    您可以通过几种方式匹配它们,例如您可以更改 string text 以匹配 formatter pattern 或其他方式。

    你可以试试这个:

    LocalDateTime
        .parse("01/01/2020 03:04:07 AM", DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss a"));
    

    另外,看看Pattern Letters and Symbols

    【讨论】:

      猜你喜欢
      • 2021-03-06
      • 2018-03-18
      • 2013-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-20
      相关资源
      最近更新 更多