Coder Social home page Coder Social logo

Comments (4)

vincentlauvlwj avatar vincentlauvlwj commented on August 22, 2024 4

看到你能自己为 Ktorm 编写扩展,我感到很高兴,因为这说明我的开源成果得到了你的认可,你也愿意花时间了解源码,并且自己动手修改。但是,如果你对上面说到的原理没有很清楚的了解的话,我认为你编写的扩展未必解决了你的问题,你最好再仔细检查一下。

最后,为了避免这种问题的再次发生,我的建议是。如果数据库中使用的是不包含时区信息的 datetime 类型,那么我们的代码中最好也使用不包含时区的 LocalDateTime 类型;如果数据库中使用的是依赖于时区的 timestamp 或者 offset date time 之类的类型,我们才应该在代码中使用 Instant 或者 ZonedDateTime。这样子一一对应,可以很好地避免出错。比如:

interface Meter : Entity<Meter> {
    ...
    var updateTime: LocalDateTime
}

object Meters : Table<Meter>("Meters") {
    ...
    val updateTime by datetime("UpdateTime").bindTo { it.updateTime }
}

谢谢你对 Ktorm 的支持,希望可以帮到你。

from ktorm.

vincentlauvlwj avatar vincentlauvlwj commented on August 22, 2024 3

在没有 Ktorm 的情况下,我们从数据库中获取一个时间的方式一般都是通过 JDBC 的 ResultSet.getTimestamp 方法,这个方法会返回一个 java.sql.Timestamp 对象。如果你直接使用这个方法的话,你会发现不管在什么时区环境下,输出的结果都会是 2019-09-29 10:00:00.000

但是,完全一样的字符串输出,在东八区和零时区下其实是不一样的,它们完全是不同的时刻,并且这两个时刻刚好相差了八个小时。因为 java.sql.Timestamp 实际上表示的是一个时间戳,里面保存了一个从零时区 1970 年 1 月 1 日 0 点开始的毫秒数。所以你看到的完全一样的字符串输出的时间,实际上里面保存的毫秒数是完全不同的。

原因你应该很清楚,sql server 中的 datetime 是不包含时区信息的,而 Java 中的 Timesamp 实际上是依赖于时区的,所以 JDBC 在读取 datetime 的值时,默认会把它解析成当前系统时区的 Timestamp 对象。在不同时区下获得的的 Timestamp 对象里面保存的毫秒数是不同的,但是 TimestamptoString 方法在输出的时候,会把毫秒数再按照当前系统时区格式化为字符串,所以你才会看到完全一样的结果。

想必你应该看过 Ktorm 的源码,在 InstantSqlType 中,我们获取 Instant 对象的方式,只是先使用 ResultSet.getTimestamp 获取到时间戳,然后再调用 Timestamp.toInstant 进行转换。这样做是完全可以的,你觉得有问题可能是对 Instant 的理解有些偏差。

Instant 是 Java 8 新增的类,它可用于替代原有的 java.util.Datejava.sql.Timestamp,用来表示时间戳的概念,可以说,它和 Timestamp 几乎是完全等价的。但是 Instant 还是和它有一点微小的差异,那就是 toString 方法。Instant.toString 方法会把它里面保存的毫秒数格式化成零时区的时间字符串,而 Timestamp.toString 方法会把毫秒数格式化成当前系统时区的时间字符串,这就是造成你误解的根源。

你看到的输出 2019-09-29T02:00:00.000Z 里面,最后面的字母 Z 即表示这是一个零时区的时间

所以,每当你看到带有字母 Z 结尾的 Instant 的输出时,先在脑子里把它加上八个小时,就知道结果到底正不正确了。

from ktorm.

vincentlauvlwj avatar vincentlauvlwj commented on August 22, 2024 2
Meters.asSequence().first().also { println(it.updateTime) }

// 数据库中 UpdateTime 字段内容为 2019-09-29 10:00:00.000
// +8时区系统(开发机)输出:2019-09-29T10:00:00.000Z
// 0时区系统(Docker)输出:2019-09-29T02:00:00.000Z

你举的这个例子可能有点问题,sql server 中的 datetime 的确是不包含时区信息的时间,如果你数据库中的字段内容是 2019-09-29 10:00:00.000 的话,理论上,在东八区的环境下应该输出 2019-09-29T02:00:00.000Z,在零时区下才应该输出 2019-09-29T10:00:00.000Z。应该是你把这两个输出弄反了,你可以再尝试一下。

小 tips,JVM 添加启动参数 -Duser.timezone=UTC 即可修改系统时区,方便测试

from ktorm.

caoddx avatar caoddx commented on August 22, 2024

您好,感谢您如此详细的回复,也感谢您的项目。由于没有检查 Google 邮箱,所以没能及时看到您的回复,非常抱歉。

两种时区下输出结果那里确实是我搞反了,你说的是对的。

我的核心问题其实是,如何对不带时区的字段进行时区化。
你给出的建议是不包含时区信息的字段使用 LocalDateTime 类型,这个确实是最应该使用的方法。
我写的扩展其实就是先转成 LocalDateTime,然后再根据时区转成 Instant,所以用起来也是没有问题的。两者的区别就是,先转换成 LocalDateTime,使用时再进行时区处理;或是一步到位直接转换成 Instant

from ktorm.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.