Comments (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.
在没有 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
对象里面保存的毫秒数是不同的,但是 Timestamp
的 toString
方法在输出的时候,会把毫秒数再按照当前系统时区格式化为字符串,所以你才会看到完全一样的结果。
想必你应该看过 Ktorm 的源码,在 InstantSqlType
中,我们获取 Instant
对象的方式,只是先使用 ResultSet.getTimestamp
获取到时间戳,然后再调用 Timestamp.toInstant
进行转换。这样做是完全可以的,你觉得有问题可能是对 Instant
的理解有些偏差。
Instant
是 Java 8 新增的类,它可用于替代原有的 java.util.Date
和 java.sql.Timestamp
,用来表示时间戳的概念,可以说,它和 Timestamp
几乎是完全等价的。但是 Instant
还是和它有一点微小的差异,那就是 toString
方法。Instant.toString
方法会把它里面保存的毫秒数格式化成零时区的时间字符串,而 Timestamp.toString
方法会把毫秒数格式化成当前系统时区的时间字符串,这就是造成你误解的根源。
你看到的输出
2019-09-29T02:00:00.000Z
里面,最后面的字母Z
即表示这是一个零时区的时间
所以,每当你看到带有字母 Z
结尾的 Instant
的输出时,先在脑子里把它加上八个小时,就知道结果到底正不正确了。
from ktorm.
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.
您好,感谢您如此详细的回复,也感谢您的项目。由于没有检查 Google 邮箱,所以没能及时看到您的回复,非常抱歉。
两种时区下输出结果那里确实是我搞反了,你说的是对的。
我的核心问题其实是,如何对不带时区的字段进行时区化。
你给出的建议是不包含时区信息的字段使用 LocalDateTime
类型,这个确实是最应该使用的方法。
我写的扩展其实就是先转成 LocalDateTime
,然后再根据时区转成 Instant
,所以用起来也是没有问题的。两者的区别就是,先转换成 LocalDateTime
,使用时再进行时区处理;或是一步到位直接转换成 Instant
。
from ktorm.
Related Issues (20)
- ktorm-support-mysql 在maven仓库中没有找到 HOT 1
- Sequence update not as expected when table column with an ON UPDATE CURRENT_TIMESTAMP clause HOT 1
- Is this still actively maintained? HOT 6
- Apache Derby DB: In case of reference entity API and using table references, ktorm generates SQL aliases with first underscore character(_) that invalid for Apache DB HOT 2
- Type mismatch.
- [Feature Request]:Field update strategist, pre positioned during insertion and update
- Connectivity problem HOT 1
- 关于join的优化
- Multiple onConflict at bulkInsertOrUpdate HOT 1
- MySQL存储UUID报错 HOT 8
- 自定义支持MySQL的find_in_set函数 HOT 5
- 适配 solon框架 HOT 1
- Union功能存在问题? HOT 2
- 关于列绑定,能不能先references再transform?
- 🧐为什么不添加支持分页的函数呢 HOT 2
- Oracle Timestamp support
- Database#exceptionTranslator should return a nullable throwable
- 4.0版本使用KSP生成实体类运行出错 HOT 8
- ksp column converter in version 4.0.0 disappeared HOT 1
- Ktorm 别名机制似乎有问题 HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ktorm.