代码之家  ›  专栏  ›  技术社区  ›  sjain

数据库中的UTC时间,其类型为“timestamp without timezone”以UTC格式显示作为响应

  •  1
  • sjain  · 技术社区  · 6 年前

    我在postgres中有一个字段的类型是“timestamp without timezone”。 这是数据库中的UTC时间,我想在API响应中显示。

    我使用以下代码在同一个UTC时区中显示它,但它在API响应中添加了本地时间偏移量-

    // date from db in UTC is 2018-06-06 09:59:04.103
    Date createdDateTime = description.getCreatedDateTime();
    SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
    isoFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
    try {
            Date date = isoFormat.parse(createdDateTime.toString());
            description.setCreatedDateTime(date);
            } catch (ParseException e) {
                LOGGER.error("An exception has occured in parsing .", e);
            }
    

    我在伊斯特的创作时间- 2018-06-06 15:16:04.103 IST 我仍在获取带有偏移量的输出作为响应: Jun 6, 2018 8:46:52 PM

    我正在使用hibernate从表中获取数据。

    2 回复  |  直到 6 年前
        1
  •  0
  •   assylias    6 年前

    此列类型应返回 Timestamp Java中的类型(或 LocalDateTime 使用JDBC 4.2+。该时间戳将包含原始日期,但在默认时区中。因此,您需要对其应用UTC时区。

    java.sql.Timestamp t = ...;
    ZonedDateTime zdt = t.toLocalDateTime() //remove time zone information
                         .atZone(ZoneOffset.UTC); //this is actually a UTC time
    

    此时,您可以继续使用 java.time 对象(如果可以,没有理由不这样做)或者可以转换 ZonedDateTime 到A java.util.Date 用:

    java.util.Date date = Date.from(zdt.toInstant());
    
        2
  •  0
  •   Basil Bourque    6 年前

    java.util.Date::toString 应用区

    您可能会被 Java.UTI.DAT::ToSoin 方法动态应用JVM的当前默认时区,同时生成一个字符串来表示 Date 根据定义,它实际上总是在UTC中。什么之中的一个 许多的 避免这个麻烦的老阶级的理由。

    数据库中的数据类型错误

    我在postgres中有一个字段的类型是“timestamp without timezone”。这是数据库中的UTC时间,我想在API响应中显示。

    这在术语上是矛盾的。sql标准 TIMESTAMP WITHOUT TIME ZONE 列不包含UTC值。该数据类型缺少时区或与UTC的偏移量的概念。(这样的UTC值应该存储在类型为 TIMESTAMP WITH TIME ZONE )

    您插入的值可能是 打算 对于UTC,但一旦存储到数据库中,就失去了这个事实。

    Java.时间

    避免 java.sql.Timestamp

    需要使用 java.sql.timestamp时间戳 . 应该避免使用那个遗留类。从jdbc 4.2及更高版本开始,我们可以直接交换 Java.时间 使用数据库键入。 Hibernate supports java.time .

    LocalDateTime

    如果缺少任何区域/偏移,则应使用 LocalDateTime 班级。该类还缺少时区或与UTC的偏移量的任何概念。

    LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class ) ;
    

    OffsetDateTime

    如果你想的话 假定 检索到的值表示UTC中的某个时刻,应用 ZoneOffset 得到 OffsetDateTime 对象。具体来说,对于UTC,我们可以使用预定义的常量 ZoneOffset.UTC .

    OffsetDateTime odt = ldt.atOffset( ZoneOffset.UTC ) ;
    

    不是 ZonedDateTime

    分区日期 从技术上讲,类将在这里代替 偏移日期时间 类,它的使用是不适当的。

    时区不仅仅是偏移量。区域是过去、现在和将来对特定区域的人使用的偏移量的变化的历史。相比之下,与UTC的偏移量仅为几个小时和分钟,不多也不少。

    所以使用一个 分区日期 在联合技术公司的这一背景下是误导性的,而且可能令人困惑。

    Instant

    现在,在你 偏移日期时间 对象,您有时间使用UTC。

    如果你知道你只想在UTC工作,从那里提取 瞬间 . 安 瞬间 根据定义总是在UTC中。当用UTC表示时刻时,通常使用 瞬间 . 如果需要更大的灵活性,例如生成各种格式的字符串,请切换到使用 偏移日期时间 .

    Instant instant = odt.toInstant() ;
    

    关于 Java.时间

    这个 java.time 框架是在Java 8和之后构建的。这些类取代了麻烦的旧类 legacy 日期时间类,如 java.util.Date , Calendar 和; SimpleDateFormat .

    这个 Joda-Time 项目,现在在 maintenance mode ,建议迁移到 java.time 类。

    要了解更多信息,请参阅 Oracle Tutorial . 和搜索堆栈溢出的许多例子和解释。规格是 JSR 310 .

    你可以交换 Java.时间 直接使用数据库的对象。使用 JDBC driver 符合 JDBC 4.2 或稍后。不需要弦,不需要 java.sql.* 类。

    在哪里获得java.time类?

    这个 ThreeTen-Extra project使用其他类扩展java.time。这个项目是将来可能添加java.time的一个试验场。你可以在这里找到一些有用的类,比如 Interval , YearWeek , YearQuarter more .