无法插入0秒的java.time.LocalDateTime



Kotlin:1.6.20

风暴:3.4.1

MySQL连接器/J:8.0.28

C3P0连接池:0.9.5.5

我似乎对";日期时间";(LocalDateTime)具有零秒。我知道这看起来像JDBC驱动程序的问题,但我测试了驱动程序,它甚至不接受LocalDateTime(只有java.util.Date)。如果LDT有秒,就不会出现这个问题。

  • 我做错什么了吗
  • 我是否缺少某些配置
  • 我的打字错了吗
  • 有人知道变通办法吗

我用来隔离问题的最低测试

const val tableName = "test"
const val fieldName = "ldt"
interface TestRecord : Entity<TestRecord> {
companion object : Entity.Factory<TestRecord>()
val ldt: LocalDateTime
}
object TestTable : Table<TestRecord>(tableName) {
val ldt = datetime(fieldName).bindTo { it.ldt }
}
class BlahTest {
@Test
fun a() {
val dataSource = DbConfig.from("test.properties").provideDataSource()
dataSource.connection.use {
it.prepareStatement("DROP TABLE IF EXISTS $tableName").execute()
it.prepareStatement("CREATE TABLE IF NOT EXISTS $tableName ($fieldName TIMESTAMP)").execute()
}
val db = Database.connect(dataSource = dataSource, dialect = MySqlDialect())
val tb = TestTable
val ldt = LocalDateTime.ofEpochSecond(0, 0, ZoneOffset.UTC)
.truncatedTo(ChronoUnit.SECONDS)
//.plusSeconds(1) // with anything but 0 it will work
db.insertOrUpdate(TestTable) {
set(tb.ldt, ldt)
}
}
}

产生错误

com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Incorrect datetime value: '1970-01-01 00:00:00' for column 'ldt' at row 1

Ktorm问题:https://github.com/kotlin-orm/ktorm/issues/391

异常将时间戳值0格式化为"1970-01-01 00:00:00",但MySQL不是。

https://dev.mysql.com/doc/refman/8.0/en/datetime.html说:

MySQL将TIMESTAMP值从当前时区转换为UTC进行存储,并从UTC转换回当前时区进行检索。(其他类型(如DATETIME)不会出现这种情况。)

例如,我处于PDT中,因此当我尝试插入时间戳值0时,它会将其调整8小时为"1969-12-31 16:00:00",这不是TIMESTAMP类型范围内的合法值。

mysql> create table tablename (ldt timestamp);
mysql> insert into tablename values (from_unixtime(0));
ERROR 1292 (22007): Incorrect datetime value: '1969-12-31 16:00:00' for column 'ldt' at row 1

因此,当您生成您的";零";值插入到CCD_ 4中。

或者您可以使用DATETIME

mysql> alter table tablename modify ldt datetime;
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0
mysql> insert into tablename values (from_unixtime(0));
Query OK, 1 row affected (0.00 sec)

无论如何,我建议使用DATETIME,因为它支持的日期范围比TIMESTAMP大。如果您需要存储2038-01-19之后的日期,这将变得非常重要。

相关内容

最新更新