【问题标题】:How to collect from a "timestamp without time zone" Field to a Java Timestamp without Timezone如何从“没有时区的时间戳”字段收集到没有时区的 Java 时间戳
【发布时间】:2020-02-24 14:36:45
【问题描述】:

我的 Jooq 查询:

dslContext.select(
                timeInterval,
                ifnull(avg(field(FieldName.AVERAGE, Double.class))
                        .cast(Double.class), 0.0))
                .from(channelTimebucketQuery)
                .groupBy(timeInterval)
                .orderBy(timeInterval)
                .collect(Collectors.toMap(Record2::component1, Record2::component2));

返回一个附有 Timezone 的 Timestamp 和一个 double

但是我的 Profiler 说它应该返回一个没有时区的时间戳。

select pg_typeof(time_bucket) from (

    select "alias_67258973"."time_bucket", coalesce(cast(avg(average) as double precision), 0.0) from (select "public"."time_bucket_gapfill"("bucket_width" := cast("public"."create_interval"("seconds" := 43200) as "pg_catalog"."interval"), "ts" := cast("public"."testTable"."time" as timestamp), "start" := cast(null as timestamp), "finish" := cast(null as timestamp)) as "time_bucket", avg("public"."testTable"."average") as "average" from "testTable" where ("public"."testTable"."device" in ('702088'  ) and "public"."testTable"."time" >= timestamp '2020-02-10 13:57:28.2212375' and "public"."testTable"."time" <= timestamp '2020-02-24 13:57:28.2222399') group by time_bucket) as "alias_67258973" group by "alias_67258973"."time_bucket" order by "alias_67258973"."time_bucket"
        ) as x;

时区从何而来?我如何将时区设置为 + 0000

【问题讨论】:

  • 如果您可以在数据库中使用timestamp with time zone 并在Java 中使用OffsetDateTime,那就更好了。 Timestamp 类设计不佳且早已过时。而timestamp without time zone 没有时间戳,这意味着它没有定义唯一的时间点。
  • Timestamp 的实例只是一个时间点,它与时区无关(因此与没有时区的 SQL 时间戳完全不同,后者是日期和时间)。 Timestamp 经常在其中保留一个时区,这非常令人困惑,但是您应该将其视为与您无关的实现细节(可能是某种优化的尝试,我不知道)。 概念上没有时区。

标签: java psql jooq timezone-offset


【解决方案1】:

SQL 类型 TIMESTAMP WITHOUT TIME ZONE(或只是 TIMESTAMP)的默认 JDBC 类型是 java.sql.Timestamp。由于历史原因,我们都感到遗憾,java.sql.Timestamp 扩展了 java.util.Date,它通过将您的 JVM 时区(即 TimeZone.getDefault())与 unix 时间戳相关联来模拟 TIMESTAMP WITHOUT TIME ZONE

SQL TIMESTAMP WITHOUT TIME ZONE 数据类型的更好表示是java.time.LocalDateTime,jOOQ 也支持。 jOOQ 的代码生成器的更新版本将设置 &lt;javaTimeTypes&gt;true&lt;/javaTimeTypes&gt; 以使 JSR-310 类型成为默认值。

尽管如此,尽管调试器和java.sql.Timestamp 中相关的隐式时区造成了混淆,但这两种数据类型彼此等价,并且可以通过以下方式相互转换:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-12
    • 1970-01-01
    • 2013-10-04
    • 2017-04-25
    • 2010-12-24
    • 2020-04-24
    • 2011-12-14
    相关资源
    最近更新 更多