【发布时间】:2016-01-20 16:12:05
【问题描述】:
我不熟悉 Java 8 及更高版本中的 java.time 格式,但我对 Joda-Time 相当熟悉,并且我非常熟悉 Java 的 java.util.Date、java.util.Calendar 和 DateFormat 类以及 ISO 8601。
我正在使用PostgreSQL 9.3 和jOOQ 3.6.4,以及包含时间戳的foo 表列:
bar timestamp with time zone NOT NULL DEFAULT CURRENT_TIMESTAMP
我使用 jOOQ 检索了 bar 值,并尝试使用 java.time 的 DateTimeFormatter.ISO_OFFSET_DATE_TIME 将其打印出来:
DateTimeFormatter timestampFormatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
Cursor<FooRecord> fooRecordCursor = createDSLContext().selectFrom(FOO).fetchLazy();
for(FooRecord fooRecord : fooRecordCursor) {
System.out.println(timestampFormatter.format(fooRecord.getBar().toInstant());
}
这会抛出一个UnsupportedTemporalTypeException:
Caused by: java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: Year
at java.time.Instant.getLong(Instant.java:608)
at java.time.format.DateTimePrintContext$1.getLong(DateTimePrintContext.java:205)
at java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:298)
at java.time.format.DateTimeFormatterBuilder$NumberPrinterParser.format(DateTimeFormatterBuilder.java:2543)
at java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2182)
at java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2182)
at java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2182)
at java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1745)
at java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1719)
但是,如果我使用自己的自定义 ISO8601DateFormat 来扩展旧式 SimpleDateFormat,我可以很好地解析该值:
final DateFormat timestampFormatter = new ISO8601DateFormat();
...
System.out.println(timestampFormatter.format(fooRecord.getBar());
我觉得这很令人困惑:
- jOOQ
bar字段访问器返回java.sql.Timestamp。在 Java 8 版本中,我将其转换为Instant,但为什么会减少可用信息量? -
Instant应该是一个绝对时间点 --- 它不是像 JodaTime 和 JavaDate一样简单地基于long偏移量吗? - 为什么
DateTimeFormatter.ISO_OFFSET_DATE_TIME期望来自Instant的Year字段?格式化程序不应该只是将long偏移量转换为当前时区的日期/时间,然后从中检索年份吗?我不希望 任何 瞬间包含Year字段。
简而言之:如果我的基于SimpleDateFormat 的ISO8601DateFormat 适用于来自PostgreSQL 的Timestamp,为什么DateTimeFormatter.ISO_OFFSET_DATE_TIME 不能弄清楚如何格式化相同值的Instant 版本?
【问题讨论】:
-
你试过
.toLocalDateTime()吗? -
toLocalDatetime()也不起作用,因为它错过了DateTimeFormatter.ISO_OFFSET_DATE_TIME格式所需的时区字段。
标签: java postgresql date-format jooq java-time