时间转换,可能真的要注意这个坑(来自SimpleDateFormat的阴暗面)

时间转换,可能真的要注意这个坑(来自SimpleDateFormat的阴暗面)

andChen 关注
0.066 字数 983 阅读 8,928

一个坑

我们经常在客户端做一些与时间相关的需求,比如 在6点~12点要展示一个新的广告位

为了解决上述问题,我们通常把 开始、结束时间格式和服务端做好约定,通过配置下发,如 startTime=2017-10-19 15:00:00
客户端用 当前时间配置时间 做对比,来完成切换。

为了防止客户端任意篡改时间,我们不会直接去读取客户端时间(也就是 System.currentTimeMillis() 转化而来的时间),我们会获取当前服务端时间(这里不做展开)。

而为了解析配置中的时间,我们需要一个常用的 SimpleDateFormat类来帮助我们解析。用法如下:

上述代码看上去毫无问题,我们将 配置中的时间 解析成了时间戳,并且,我们还注意到了时区问题,使用了Locale.CHINA 东8区来解析,规避掉了用户手动切时区而导致解析异常(因为 我们的服务器时间是采用了东8区时间)。恩,总而言之,非常棒。

于是乎,我们代码上线了,等到了2017-10-19 15点,静静等待着广告位流量暴增。

可是还没到15点,11点......一波流量进来、12点.... 流量曲线变抖了、13点.....继续爆发...

来来,review一波

整点流量曲线变化明显,很快意识到可能被时区坑了 。

由于获取服务端时间已经上线很久了大量业务方在使用,没出现过时区问题。所以直接被排除。
剩下的,就是这3行代码了。。。。

因此不得不来检查一下 这3行代码。。What fuck ,你告诉我,这么和谐用法,特喵有什么问题。。

Run 一下

肉眼是看不出来什么问题了,跑一下。

Out put:

time:1508396400000

反查之:1508396400000 ->Thu Oct 19 2017 15:00:00 GMT+0800 (CST)

接着切换本地时区,切到东9区:
Out put:

time:1508392800000

反查之:1508392800000 ->Thu Oct 19 2017 14:00:00 GMT+0800 (CST)

真的。。。。。提前了。。。。。 一个小时。。。。Locale.CHINA,这个参数,摆设么?


问题定位了,SimpleDateFormat的错误用法,导致配置时间解析出错,非东8区的用户,就会存在时间不准问题。

SimpleDateFormat ,我还敢信你么?

在我吐槽了半小时SimpleDateFormat后,我认真打开了源码,习惯性的读了一下类注释:

可知,有3个用法:

  • formatting(date -> text)
  • parsing (text -> date)
  • normalization

我们用到的是parse

parse

可知,parse中的 时区,来自于 TimeZone。而SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA)中的Locale.CHINA并非设置时区,而是在:

SimpleDateFormat

构造方法中的 locale ,被传入DateFormatSymbols.getInstanceRef(locale);中,作为设置 formatData的格式,这个参数,会在 formatting(date -> text)用法中生效。

因此,我们需要 正确的设置解析时区,应该去设置 TimeZone
SimpleDateFormat暴露了setTimeZone(TimeZone zone) 方法可以设置时区。

setTimeZone

由此,我们可以理解Locale.CHINA失效的原因。

正确用法

parsing (text -> date)

将时间字符串,转换成正确的Date

无论修改到任何时区,都将输出东8区时间:

time:1508396400000
formatting(date -> text)

Date转化成指定时区的 时间字符串格式。
这个只会根据国家来改变展示格式.

输出:

//系统语言是中文
time:公元 2017/十一月/05 22:42:14 周日 下午  中国标准时间
//系统语言是英文
time:AD 2017/November/05 22:45:22 Sun PM  China Standard Time

指定第二个参数后:

//系统语言是中文
time:公元 2017/十一月/05 22:42:14 周日 下午  中国标准时间
//系统语言是英文
time:公元 2017/十一月/05 22:45:56 周日 下午  中国标准时间

其实都是细节,注意使用,避免入坑。。

..

10人点赞
"小礼物走一走,来简书关注我"
赞赏支持 还没有人赞赏,支持一下
总资产2 (约0.22元) 共写了5936字 获得74个赞 共27个粉丝
关注
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值