日期格式问题与DateTimeFormatter

huangapple go评论85阅读模式
英文:

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' 无法在索引 0 处解析

有人能帮帮我吗?

英文:

I have a date in the following format: 1/1/2020 3:4:7 AM I am trying to format it using DateTimeFormatter.

I have the following code with a formatter to parse it, but it doesn't work.

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

I get the following exception:

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

Can anyone help me?

答案1

得分: 8

错误计数

您正在使用例如MM的明确格式:始终是完整的零填充数字。您的字符串不是这样的,它只是数字。所以,请将它更改为M/d/uuuu h:m:s a

编辑:将yyyy更改为uuuu,感谢@deHaar。推理:yyyyuuuu很少重要,但请注意,这意味着需要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));

效果很好。

英文:

Two separate problems:

Wrong counts

You're using e.g. MM which is an explicit: Always the full amount of digits, zero-padded. Your string is not like that, it's just the number. So, make that M/d/uuuu h:m:s a.

EDIT: Changed yyyy to uuuu, thanks, @deHaar. Reasoning: yyyy or uuuu rarely matters, but note that this mean 4 digits are required. The difference kicks in for years before 0: uuuu goes negative, yyyy does not and expects you to use e.g. GG so that you get 44 BC instead of -44. In that way, uuuu is just more correct, even though usually the difference is not going to come up.

Missing locale

The second problem is that you should pretty much never use this version of ofPattern - it has a bug, which you can't catch with unit tests, which makes that a bug that is thousands of times 'heavier', and thus, a real problem.

You need to specify locale. Without it, 'AM' is not going to parse unless your platform default locale is english.

Putting it together

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

works great.

答案2

得分: 4

  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) {
        // 以不区分大小写的方式处理模式的格式化程序(例如 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
英文:
  1. Use single letters for date and time components (month, day, year, hour, minute, and second).

  2. You can also make the formatter handle the pattern in a case insensitive way (e.g. am, AM, Am) as shown below:

    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);
        }
    }
    

Output:

2020-01-01T03:04:07

答案3

得分: 4

在您的代码片段中:

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

英文:

In your snippet:

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

i.e. the lengths of the formatter pattern parts (e.g. MM) and their respective parts from the string text (e.g. 1) do not match.

You can match them in a few ways, e.g. you can either change the string text to match the formatter pattern or other way around.

You can try this instead:

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

Additionally, have a look at the Pattern Letters and Symbols.

答案4

得分: 2

根据DateTimeFormatter的文档

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

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

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

According to the 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.

By reversing the reasoning, you can try using this formatter instead:

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

huangapple
  • 本文由 发表于 2020年10月5日 22:01:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/64210169.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定