SimpleDateFormat
是Java用于构造与解析时间格式的类,虽然在多线程上有漏洞,但还是挺常用的。
这里记录一下我遇到的问题。
1 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.sss"); |
上面这段代码在早上运行是没有问题的,但是到了下午就会发现这玩意会少12小时。
代码写得多的阿猿肯定看出来了,hh
表示的是 12进制 的小时,这里应该用HH
来表示 __24进制__。注意,这里的sss
也是有问题的,应该用SSS
这个问题是我在从数据库获取日期,然后返回给前端的时候出现的。最初我以为是数据库的时区没设置对。但是我去数据库查数据时,时间又是正常的。
数据库排除后,我又担心是我传给前端时出现了时区问题,所以就直接在本地打印了。然后时间就出错了。找到问题出现的地点后,就该排查问题根源了。
首先我先排查的时区,因为很巧的是只有小时数错误,而且是12小时。我以为是那种加个GMT+8
的问题,就对SimpleDateFormat
设了时区,不行。设置后,时间会走4个小时,然后就只差了8小时。这个就很干扰我了,这个8小时就是我们时区的时差。然后我就一直按着这条错误路线排查,一直都没有解决。
我差点想对小时单独处理了,不过我还是先把这个问题给了我的一个同事。他表示没有遇到过这个问题,然后又在自己电脑上自己敲了一遍,时间正常的。
我就让同事把他的代码发给我,我来试一下(我开始相信玄学了)。运行后时间是正常的,啊这。。。到这里我都还没有发现是时间格式的问题,直到我同事让我把我之前的代码发给他。我发过去之后,他一下就看出问题了。嗯,挺好。
这里附一份时间格式表
字母 | 日期或时间元素 | 表示 | 示例 |
---|---|---|---|
G | Era标志符 | Text | AD |
y | 年 | Number | 2022;22 |
M | 月 | Number | 02;Feb |
w | 年中周 | Number | 10 |
W | 月中周 | Number | 2 |
d | 月中天 | Number | 22 |
D | 年中天 | Number | 72 |
F | 月中周 | Number | 4 |
E | 星期 | Text | Tue;星期二 |
a | 时段 | Text | AM;PM |
h | 小时(12进制)(1 - 12) | Number | 8 |
H | 小时(24进制)(0 - 23) | Number | 16 |
m | 时中分钟 | Number | 23 |
s | 分中秒 | Number | 27 |
S | 秒中毫秒 | Number | 271 |
k | 小时(24进制)(1 - 24) | Number | 11 |
K | 小时(12进制)(0 - 11) | Number | 00 |
z | 时区(文字表示) | Text | CST |
Z | 时区(数字表示) | Text | +0800 |