Mysql?DateTime?查詢問題解析
正文
/** * The maximum supported {@code LocalTime}, '23:59:59.999999999'. * This is the time just before midnight at the end of the day. */ public static final LocalTime MAX; /** * The maximum supported {@code LocalDateTime}, '+999999999-12-31T23:59:59.999999999'. * This is the local date-time just before midnight at the end of the maximum date. * This combines {@link LocalDate#MAX} and {@link LocalTime#MAX}. * This could be used by an application as a "far future" date-time. */ public static final LocalDateTime MAX = LocalDateTime.of(LocalDate.MAX, LocalTime.MAX);
我們可以看到 LocalTime 和 LocalDateTime 的精度是可以去到 9 也就是達到納秒
但是為什么我們經(jīng)常打印出來的時候往往只有小數(shù)點后三位、也就是毫秒
LocalDateTime now = LocalDateTime.now(); System.out.println(now);
調(diào)用System的currentTimeMillis
我們看到源碼最終還是調(diào)用了 System的currentTimeMillis
@Override public long millis() { return System.currentTimeMillis(); } @Override public Instant instant() { return Instant.ofEpochMilli(millis()); }
最近測試環(huán)境中出現(xiàn)了個時間精度的問題、計算某個流程所花費的時間的時候得出了負數(shù)、因為存儲該字段的類型設(shè)置了無符號、導(dǎo)致插入的時候報錯、超出該類型的值的范圍。
當時的第一反應(yīng)是流程對應(yīng)的步驟是不是分別在不同的容器中執(zhí)行、容器之間是否存在時間差。
后面排查所有的步驟均執(zhí)行在同一個容器中、日志打印的時間和sql插入的值均沒啥差異。select 出來的值沒有打印出來。
后面看到其中日志打印insert 的值的秒比數(shù)據(jù)庫中的秒要少一秒。然后發(fā)覺沒有設(shè)置 dateTime 的精度
這個其實是錄入表的同事遺漏了、原本設(shè)計表結(jié)構(gòu)是有6位精度的(規(guī)范要求)。
后面補上精度、順手將無符號也去掉
Mysql 中的 dateTime 精度默認為 0 、最大可以去到 6。
如果入?yún)⒌木却笥?dateTime 的精度、那么將會進行四舍五入。
小結(jié)
插入的時候、如果輸入的精度比聲明的精度高、那么則會對其進行四舍五入
查詢
值得注意的是、LocalTime | LocalDateTime 的 MAX 是 9位 的、如果
drop table mqst1; create table mqst1 ( id int null, createtime datetime(0) null ); INSERT INTO test_schema.mqst1 (id, createtime) VALUES (1, '2021-10-01 21:08:08.123'); INSERT INTO test_schema.mqst1 (id, createtime) VALUES (1, '2021-10-01 23:59:59.567'); INSERT INTO test_schema.mqst1 (id, createtime) VALUES (2, '2021-10-02 00:00:00.000'); select * from mqst1 where createtime >= '2021-10-01 00:00:00' and createtime <= '2021-10-01 23:59:59.999999'; select * from mqst1 where createtime >= '2021-10-01 00:00:00' and createtime <= '2021-10-01 23:59:59.9999995';
第二條的查詢就最后的參數(shù)比第一條的時間多了一個 5
首先看插入結(jié)果
那么第一條的查詢結(jié)果是只有一條
第二條的查詢結(jié)果卻是 3 條。
因為 mysql 將字符串轉(zhuǎn)換成 dateTime 的時候使用的是 6 位的精度、超過六位的才會四舍五入、所以導(dǎo)致第二條的查詢條件變?yōu)?10-02 00:00:00
我們將 dateTime 的精度改為 2
createtime datetime(2) null
那么第一條的查詢結(jié)果為兩條
而第二條的查詢結(jié)果還是為三條
即使將精度改為6也是這樣的結(jié)果
總結(jié)
對于查詢而已、mysql 會對 string 的轉(zhuǎn)換如果超出 6 位 多出的會進行四舍五入、然后才會去表中進行比較
事實上對于大多數(shù)場景而已、Java 提供的毫秒級別的時間以及能滿足大多數(shù)場景了、對應(yīng)到 db 存儲時間到精度、
建議直接 6 會比較省心點吧、跟 Mysql 做字符串轉(zhuǎn)換 dateTime 的時候一樣。
查詢到時候需要注意的是如果上限被包含進去、需要考慮精度是否超過 Mysql 的最大精度、如果超過了則可能你會被舍入
System.out.println(LocalDateTime.of(LocalDate.now(), LocalTime.MAX).withNano(999999000));
以上就是Mysql DateTime查詢問題解析的詳細內(nèi)容,更多關(guān)于Mysql DateTime的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
MySQL中的聚簇索引、非聚簇索引、聯(lián)合索引和唯一索引詳細介紹
本文主要介紹了MySQL的索引類型,根據(jù)索引的存儲方式來劃分,索引可以分為聚簇索引和非聚簇索引。聚簇索引的特點是葉子節(jié)點包含了完整的記錄行,而非聚簇索引的葉子節(jié)點只有所以字段和主鍵ID,感興趣的同學(xué)可以閱讀本文2023-04-04Mysql啟動中 InnoDB: Error: log file ./ib_logfile0 is of differe
對于使用了默認 my.cnf(一般教程都會教你使用support-files/my-medium.cnf)的Mysql服務(wù)來說如果中間使用了innodb的話,innodb默認的log file大小是56M2011-05-05Mysql的數(shù)據(jù)庫遷移到另一個機器上的方法詳解
今天小編就為大家分享一篇關(guān)于Mysql的數(shù)據(jù)庫遷移到另一個機器上的方法詳解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-04-04MySQL計劃任務(wù)(事件調(diào)度器) Event Scheduler介紹
MySQL5.1.x版本中引入了一項新特性EVENT,顧名思義就是事件、定時任務(wù)機制,在指定的時間單元內(nèi)執(zhí)行特定的任務(wù),因此今后一些對數(shù)據(jù)定時性操作不再依賴外部程序,而直接使用數(shù)據(jù)庫本身提供的功能2013-10-10MySQL性能優(yōu)化之Open_Table配置參數(shù)的合理配置建議
這篇文章主要介紹了MySQL性能優(yōu)化之Open_Table配置參數(shù)的合理配置建議,在MySQL數(shù)據(jù)庫中,Opened_tables表示打開過的表數(shù)量,需要的朋友可以參考下2014-07-07MYSQL數(shù)據(jù)庫導(dǎo)入數(shù)據(jù)時出現(xiàn)亂碼的解決辦法
我是用的最后一種方法,前面三種解決MYSQL導(dǎo)入數(shù)據(jù)亂碼的方法沒試過,東莞SEO推薦大家直接使用第四種方法處理MYSQL導(dǎo)入中文數(shù)據(jù)時的亂碼問題。2011-01-01