jOOQ:如何在自定义时区创建时间戳(与JDBC一样)?

时间:2014-03-31 17:49:34

标签: mysql datetime jdbc jooq

短版

在MySQL数据库中,我有一个数据类型为DATETIME的列。使用JDBC,可以将这些值设置为timestamps in a certain timezone。这可以用jOOQ来完成吗?

更长的版本

我有一个包含此架构的示例表:

CREATE SCHEMA IF NOT EXISTS `my_test_db` DEFAULT CHARACTER SET utf8 COLLATE utf8_bin ;
CREATE  TABLE IF NOT EXISTS `my_test_db`.`my_table` (
  `id` INT NOT NULL AUTO_INCREMENT ,
  `my_time` DATETIME NOT NULL ,
  PRIMARY KEY (`id`) )

我对DATETIME列中的TIMESTAMP列,特别感兴趣。我只想使用UTC时间戳 - 无论我在哪里查询数据,从哪里得到时间戳都要插入数据库。

使用JDBC,我可以像在此示例应用程序中一样解决问题:

import java.sql.*;
import java.util.Calendar;
import java.util.TimeZone;

public class MyTest {
  public static void main(String[] args) throws Exception {

    Class.forName("com.mysql.jdbc.Driver");
    Connection conn = null;
    try {
      conn = DriverManager.getConnection("jdbc:mysql://localhost/my_test_db?"
        + "useTimezone=true&useLegacyDatetimeCode=false&serverTimezone=UTC");

      PreparedStatement prepStmt = conn.prepareStatement(
         "INSERT INTO `my_test_db`.`my_table` (`my_time`) VALUES (?)");

      // NB: this particular timestamp is just an example; I actually get
      // timestamps from elsewhere but I can be certain that they’re in UTC.
      Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));

      // This is the interesting line which I’d like to port to jOOQ; I can pass
      // in an additional “Calendar” object from which time zone information is
      // taken into account for the new “DATETIME” value:
      prepStmt.setTimestamp(1, new Timestamp(cal.getTimeInMillis()), cal);
      prepStmt.executeUpdate();
    } finally {
      if (conn != null) {
        conn.close();
      }
    }
  }
}

在jOOQ中,我似乎无法指定时区信息:

// …
DSLContext dslContext = DSL.using(conn);
dslContext.insertInto(MY_TABLE)
  .set(MY_TABLE.MY_TIME, new Timestamp(cal.getTimeInMillis()))
  .execute();

因此,使用上述jOOQ代码创建的任何时间戳都在系统默认时区。我可以改变吗?

2 个答案:

答案 0 :(得分:0)

我使用一个新类来解决它,返回一个实现utc_timestamp()函数的jOOQ字段。

package org.jooq.impl;

import ...

public class Custom_MySQL_UTCTimestamp extends AbstractFunction<Timestamp> {

    public Custom_MySQL_UTCTimestamp() {
        super("utc_timestamp", SQLDataType.TIMESTAMP);
    }

    @Override
    final Field<Timestamp> getFunction0(Configuration configuration) {
        if(configuration.family() == SQLDialect.MYSQL){
            return function("utc_timestamp", SQLDataType.TIMESTAMP);            
        }
        return function("current_timestamp", SQLDataType.TIMESTAMP);    
    }
}

请注意,您必须保留包名称org.jooq.impl。

然后在我的代码中我使用它:

InsertSetMoreStep<TableRecord> insert = db.insertInto(TABLE)
    .set(TABLE.DATE,new Custom_MySQL_UTCTimestamp())

TABLE.DATE属于MySQL类型DATETIME

答案 1 :(得分:0)

您可以通过以下方式完成此操作:

Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("Europe/Madrid"));
long currentTime = calendar.getTimeInMillis();

然后使用JOOQ进入你的桌子:

dslContext.insertInto(MY_TABLE)
  .set(MY_TABLE.MY_TIME, new Timestamp(currentTime))
  .execute();

编辑:以上只会保存Chriki在下面的评论中提到的UTC时间。

但是,这可能有效:

long currentTime = calendar.getTimeInMillis() + TimeZone.getTimeZone("America/New_York").getOffset(Calendar.getInstance().getTimeInMillis())

https://www.tutorialspoint.com/java/util/timezone_getoffset_date.htm 基本上,找到UTC的偏移量,然后将其添加到当前的UTC时间。