将字符串转换或格式化为日期

Convert or format string to date

我正在为此苦苦挣扎.. 我有一个输入字符串 - 像这样:2021-10-13 11:33:16.000-04

使用 Java.

我需要从中获取一个 Date 对象。 我可以使用哪种格式化模式?

我试试这些

SimpleDateFormat inFormatter = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss.SSS'-'ZZ");

SimpleDateFormat inFormatter = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss.SSSZZ");

而且我不断得到

java.text.ParseException: Unparseable date: "2021-10-13 11:33:16.000-04"
  at java.base/java.text.DateFormat.parse(DateFormat.java:396)
  at com.dima.tests.DatesConversions.main(DatesConversions.java:24)

请帮忙!!

由于您使用的是 ISO 8601 time zone 时区,因此您可以使用以下模式。

SimpleDateFormat inFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSX");

然后,获取日期:

Date date = inFormatter.parse("2021-10-13 11:33:16.000-04");

始终检查 documentation

不要使用日期,因为它已过时。在 java.time

中使用 类
OffsetDateTime odt = OffsetDateTime.parse(str, 
    DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSX"));       
System.out.println(odt);

版画

2021-10-13T11:33:16-04:00

java.time

即使您需要将旧式 Date 对象提供给您无法控制的遗留 API,我仍然建议您使用 java.time,现代 Java 日期和时间 API,在你自己的代码中。最终转换为 Date 非常简单。

我会使用这个格式化程序来最大程度地重用现有的格式化程序:

private static final DateTimeFormatter PARSER = new DateTimeFormatterBuilder()
        .append(DateTimeFormatter.ISO_LOCAL_DATE)
        .appendLiteral(' ')
        .append(DateTimeFormatter.ISO_LOCAL_TIME)
        .appendOffset("+HHmm", "+00")
        .toFormatter(Locale.ROOT);

然后我们这样解析转换:

    String input = "2021-10-13 11:33:16.000-04";
    OffsetDateTime dateTime = OffsetDateTime.parse(input, PARSER);
    System.out.println(dateTime);
    
    Instant i = dateTime.toInstant();
    Date oldfashionedDate = Date.from(i);
    System.out.println(oldfashionedDate);

在我的时区输出,Europe/Copenhagen:

2021-10-13T11:33:16-04:00
Wed Oct 13 17:33:16 CEST 2021

每年这个时候,丹麦的偏移量为 +02:00,因此比字符串中的 UTC 偏移量 -04 提前 6 小时。因此,Date.toString() 会混淆地打印比原始时间提前 6 小时的时钟小时。

注意:如果您的转发服务接受除老式 Date 之外的任何其他内容,您不应该使用那个 class。例如,如果需要 String,我们得到的 OffsetDateTime 可以使用第二个 DateTimeFormatter(或者在幸运的情况下,它的 toString 方法格式化为新字符串).

你的代码出了什么问题?

首先,UTC 偏移量可以有正号或负号。例如 +09,而不是 -04。格式化程序旨在将符号 +- 作为偏移量的一部分。因此,如您的第一次尝试那样,将减号硬编码为文字,注定会失败。在你的第二次尝试中,yyyy-MM-dd HH:mm:ss.SSSZZ,你已经接近了。但是,ZZ 用于带符号的偏移量和 四个 数字(如 +0530-0400;小时和分钟),因此不适用于一个两位数的偏移量,如 -04。您的 SimpleDateFormat 期望字符串结尾处有更多数字,因此引发了您看到的异常。

Link

Oracle tutorial: Date Time 解释如何使用 java.time.