首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法在零秒内插入java.time.LocalDateTime

无法在零秒内插入java.time.LocalDateTime
EN

Stack Overflow用户
提问于 2022-05-03 15:19:56
回答 1查看 125关注 0票数 1

Kotlin: 1.6.20

Ktorm: 3.4.1

MySQL连接器/J: 8.0.28

C3P0连接池: 0.9.5.5

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

  • 我做错了什么吗?
  • 我是不是漏掉了什么配置?
  • 我搞错类型了吗?
  • 有人知道解决办法吗?

用于隔离问题的最小测试

代码语言:javascript
复制
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)
        }
    }
}

产生错误

代码语言:javascript
复制
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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-05-03 15:36:59

例外情况是将时间戳值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时,它会将时间戳值调整为'1969-12-31 16:00:00',这不是TIMESTAMP类型范围内的合法值。

代码语言:javascript
复制
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

因此,在生成要插入到TIMESTAMP中的“零”值时,可以确保说明时区。

或者你可以用DATETIME

代码语言:javascript
复制
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的日期

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72101678

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档