最新消息:相关的技术文章和资料收集整理,感谢大家支持。

iOS客户端NSDateFormatter那些坑

iOS平台 djwangping 10714浏览
NSDateFormatter 会收到用户偏好设置的影响,所以有一些坑:
初始化为各种日历。identifier的范围可以是:
NSGregorianCalendar 阳历
NSBuddhistCalendar 佛历
NSChineseCalendar 中国日历
NSHebrewCalendar 希伯来日历
NSIslamicCalendar 伊斯兰日历
NSIslamicCivilCalendar 伊斯兰民事日历
NSJapaneseCalendar 日本日历

时区校验

有时候,我们需要把时间字符串转换为long类型的时间戳。比如下面例子:

但这里忽略了时区问题:
我们从模拟器中,“设置”-> “通用” -> “时间与日期” ->关闭自动设置,选择”纽约”时区。上面代码计算出的time值 为1454734800000。 然后我们选“北京”时区,计算出的time值为 1454688000000显然,两个值不一样,而且在纽约时区下计算出的时间戳的值更大。

UTC (Coordinated Universal Time)

我们来看timeIntervalSince1970函数,官方说明

整个地球分为二十四时区,每个时区都有自己的本地时间。但是在全球范围,我们需要一个标准时间。我们熟悉的标准时间是 格林尼治时间。格林尼治标准时间(中国大陆翻译:格林尼治平均时间或格林尼治标准时间,台、港、澳翻译:格林威治标准时间;英语:Greenwich Mean Time,GMT)是指位于英国伦敦郊区的皇家格林尼治天文台的标准时间,因为本初子午线被定义为通过那里的经线。自1924年2月5日开始,格林尼治天文台每隔一小时会向全世界发放调时信息。理论上来说,格林尼治标准时间的正午是指当太阳横穿格林尼治子午线时(也就是在格林尼治上空最高点时)的时间。由于地球在它的椭圆轨道里的运动速度不均匀,这个时刻可能与实际的太阳时有误差,最大误差达16分钟。由于地球每天的自转是有些不规则的,而且正在缓慢减速,因此格林尼治时间已经不再被作为标准时间使用。现在的标准时间,是由原子钟报时的UTC。其以原子时秒长为基础,在时刻上尽量接近于格林尼治标准时间。

北京时区是东八区,领先UTC八个小时。时区差东为正,西为负。在此,把东八区时区差记为 +0800。纽约的时区是西五区,比UTC落后五个小时,记为 -0500. 即北京时间领先纽约时间十三个小时.

UTC 时间为1970年1月1号00:00:00的时候。北京时间是1970年1月1号8点,纽约时间还是1969年12月31号19:00。想象,每个时区有自己的时间坐标轴,原点代表的时间点是UTC的“1970年1月1号00:00:00”, 在坐标上标出各自的”2016-02-06 00:00:00″这一点,它们离原点的距离就是我们要算的时间戳。

timetamp.png

显然,将”2016-02-06 00:00:00″转化为格林尼治标准的时间戳。在纽约时区计算出来的值要比北京时区大。

如果将”2016-02-06 00:00:00″是服务端(东八区)下发的时间,我们在客户端需要转为时间戳,建议,把NSDateFormatter的时区设定在东八区。

Paste_Image.png

timeZone

timeZone

日历校验

iOS 设置->通用->语言与地区->日历。有公历日本日历佛教日历.公元2016年,日本日历是平成28年。佛历2560年。
所以如果用户在设置中选日本日历,上面代码计算的l时间戳又不一样了:64189900800

补救方法: 手工设置NSDateFormatter的日历

或者设置locale.日历可以由NSLocale 中 NSLocaleCalendar这个属性指定
官网说明:

12 小时制 和24小时制

  • HH :24小时制
  • hh :12 小时制

这是iOS SDK3.1的bug,在设置中时区自动为纽约的时候,24小时制会自动关闭。自动为法国时区的时候,24小时制会开启。但是如果法国用户手动选择12小时制,”HH”的格式不起作用,程序返回的是”01:00 PM”这12小时类型的日期。

参考博客:

YYYY和yyyy

working with Date and Time

  • yyyy is ordinary calendar year.
  • YYYY is week-based calendar year.“将这一年中第一周的周日当作今年的第一天”.因此有时结果和yyyy相同,有时就会不同

Date Field Symbol Table

语言和时间制

没错 0 0 ,这也有坑。比如一些日漫粉会把语言选为 “日语”,关闭”24-小时制”. 这时候:

这样的代码NSDate对象为null.time为0.
换”时区”或者” 地域”后手动把24-小时制关闭,还是返回null. 具体原因,暂不明白。

此时开启”24-小时制”或者format的格式改HH为hh format setDateFormat:@"yyyy-MM-dd hh:mm:ss"]又有值返回。12小时制和24小时制

方法:

NSLocale对象可以指定语言。

输出结果:

不同时区城市

文/蓝新(简书作者)
原文链接:http://www.jianshu.com/p/73b13a42f1cb
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

转载请注明:Mibugs.com » iOS客户端NSDateFormatter那些坑