DateTimeFormatter 的日期格式问题

Date Format Issue With DateTimeFormatter

我有一个格式如下的日期: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

谁能帮帮我?

  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

两个不同的问题:

计数错误

您正在使用例如MM 这是一个显式:始终是全部数字,zero-padded。你的字符串不是那样的,它只是数字。所以,让 M/d/uuuu h:m:s a.

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

缺少语言环境

第二个问题是你应该 永远不要 使用这个版本的 ofPattern - 它有一个错误,你无法通过单元测试发现它,这使得该错误成为数千次 'heavier',因此成为一个真正的问题。

您需要指定语言环境。没有它,'AM' 将不会解析,除非您的平台默认语言环境是英语。

放在一起

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

效果很好。

根据 documentation of DateTimeFormatter:

Number: If the count of letters is one, then the value is output using the minimum number of digits and without padding. Otherwise, the count of digits is used as the width of the output field, with the value zero-padded as necessary.

通过逆向推理,您可以尝试改用此格式化程序:

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

在您的代码段中:

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中的相应部分) 不匹配。

您可以通过几种方式匹配它们,例如您可以更改 字符串文本 以匹配 格式化程序模式 或其他方式。

您可以试试这个:

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

此外,请查看 Pattern Letters and Symbols