今天一大早公司客服就反馈了一个问题,客户端的时间出现了一个很诡异的问题:过期的券显示过期时间是2018-12-31。2018年才过了一天,而且还是已经过期的,应该是2017才对。
通过debug发现,服务端传的时间戳是没问题的,那就只能是客户端时间戳转换的问题了。可是换了几个时间戳都没问题,实验了一下1483146000(2016-12-31 09:00:00)和1546218000(2018-12-31 09:00:00)时间戳之后,发现1546218000这个时间戳也出现了同样的问题。检查代码发现时间戳的转换方法没有任何问题,然后查了官方文档,官方文档给的demo是这样的:
RFC3339DateFormatter = [[NSDateFormatter alloc] init];
RFC3339DateFormatter.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
RFC3339DateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ssZZZZZ";
RFC3339DateFormatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
(https://developer.apple.com/documentation/foundation/nsdateformatter?language=objc)
对比发现我们客户端设置formatter的格式是使用的是‘YYYY-MM-dd HH:mm:ss’,在year转换时,用的是‘YYYY’,官方文档用的‘yyyy’,然后我就将大写改为小写试了一下,然后问题就解决了。
也就是说问题在year转换时出的问题,Google了一下,发现iOS确实有这方面的问题,解释是这么说的:
YYYY是以周来计算年的,意思是当天所在周属于的年份,一周从周日开始算计算,周六结束,只要本周跨年,那么这一周就算下一年的。
也就是说:年份如果用Y会是这周的年份,y才是标准的年份。
这一点官方文档没说明,所以还是自己注意点吧,以后转换日期格式的时候记得还是用@“yyyy-MM-dd”这种格式吧,避免出现这种情况衍生的bug。
使用NSDateFormatter转换时间格式,需要的参数如下:
G: 公元时代,例如AD公元
yy: 年的后2位
yyyy: 完整年
MM: 月,显示为1-12
MMM: 月,显示为英文月份简写,如 Jan
MMMM: 月,显示为英文月份全称,如 Janualy
dd: 日,2位数表示,如02
d: 日,1-2位显示,如 2
EEE: 简写星期几,如Sun
EEEE: 全写星期几,如Sunday
aa: 上下午,AM/PM
H: 时,24小时制,0-23
K:时,12小时制,0-11
m: 分,1-2位
mm: 分,2位
s: 秒,1-2位
ss: 秒,2位
S: 毫秒
常用日期结构:
yyyy-MM-dd HH:mm:ss.SSS
yyyy-MM-dd HH:mm:ss
yyyy-MM-dd
MM dd yyyy