格式化 ZonedDateTime 和 return ZonedDateTime

Format ZonedDateTime and return ZonedDateTime

我有以下 ZonedDateTime 对象:

ZonedDateTime z1 = ZonedDateTime.parse("2021-08-06T19:01:32.632+05:30[Asia/Calcutta]");

需要 return 另一个 ZonedDateTime 对象,其值为:06-Aug-2021 19:01:32 IST[​​=13=]

我可以像下面这样格式化:

DateTimeFormatter df = DateTimeFormatter.ofPattern("dd-MMM-yyyy HH:mm:ss zz");
 String s = z1.withZoneSameInstant(ZonedDateTime.now().getZone()).format(df);

但我需要 return ZonedDateTime 而不是 String。 我现在如何将其转换回 ZonedDateTime。如果我再次解析时区变化或时间值发生变化。

ZonedDateTime 没有格式,没有文本

but I need to return ZonedDateTime not String.

简答:不可能。

解释:

标准日期时间 classes 没有任何属性来保存格式信息。即使某些库或自定义 class 承诺这样做,它也违反了 Single Responsibility Principle。日期时间对象应该存储有关日期、时间、时区等的信息,而不是格式。以所需格式表示日期时间对象的唯一方法是使用日期时间 parsing/formatting 类型将其格式化为 String

  • 现代日期时间 API: java.time.format.DateTimeFormatter
  • 对于旧版日期时间APIjava.text.SimpleDateFormat

时区 ID 的 3 个字母缩写:

3 个字母缩写的问题,例如IST是可以指定多个时区;因此,您需要根据命名约定将其更改为所需的时区 ID,Region/City。以下是 documentation:

的摘录

Three-letter time zone IDs

For compatibility with JDK 1.1.x, some other three-letter time zone IDs (such as "PST", "CTT", "AST") are also supported. However, their use is deprecated because the same abbreviation is often used for multiple time zones (for example, "CST" could be U.S. "Central Standard Time" and "China Standard Time"), and the Java platform can then only recognize one of them.

演示:

import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        ZonedDateTime z1 = ZonedDateTime.parse("2021-08-06T19:01:32.632+05:30[Asia/Calcutta]");
        DateTimeFormatter df = DateTimeFormatter.ofPattern("dd-MMM-yyyy HH:mm:ss z", Locale.ENGLISH);
        String s = z1.format(df);
        System.out.println(s);

        // Getting the original ZonedDateTime from the string
        s = s.replace("IST", "Asia/Calcutta");
        ZonedDateTime z2 = ZonedDateTime.parse(s, df);
        System.out.println(z2);
    }
}

输出:

06-Aug-2021 19:01:32 IST
2021-08-06T19:01:32+05:30[Asia/Calcutta]

ONLINE DEMO

为什么不直接使用重载版本 parse(CharSequence t, DateTimeFormatter f),如:

ZonedDateTime z1 = ZonedDateTime
        .parse("2021-08-06T19:01:32.632+05:30[Asia/Calcutta]", DateTimeFormatter.ISO_ZONED_DATE_TIME);

或者,如果您坚持要拥有两个不同的对象:

String zdt = "2021-08-06T19:01:32.632+05:30[Asia/Calcutta]";

ZonedDateTime z1 = ZonedDateTime.parse(zdt);
ZonedDateTime z2 = ZonedDateTime.parse(zdt, DateTimeFormatter.ISO_ZONED_DATE_TIME);