tuy

偶遇IOS8和IOS9中Javascript的Date问题

一:前言

事情发生在刚刚完成的11月份超值抢活动,添加了倒计时功能,并且考虑到每个手机的本地时间不一致,为了严谨期间,索性把当前时间通过服务器来传递给前端界面。

二:代码实现

功能实现过程非常顺利,当距离开抢时间大于一个小时的时候,不显示分秒,直接显示具体时间;小于一小时,直接进入逐秒刷新的时刻倒计时。

主要是两个时间点,一个是var Now = new Date("time of Service")代替手机端的本地时间new Date();另外一个是End的时间点,绑定在dom元素time的startTime属性值中,也同样是由服务器设置的开抢时间

DOM结构:

<section id="133" class='gray'>
	<div class="item">
		 <div class="left">
		   <a href="javascript:void(0)" ><img src='/weixin/resource/images/loading.png'  data-src="http://coupon.96225.com/coupon/upload/20151214154636.png"></a>
			<article style="display:none">
			<h1 class='setover'>5折</h1>
			 <ul>
				<li><span>现价:¥</span><i>¥</i></li>
				<li>有效期至:2015-12-24</li>
			 </ul>
		   </article>
		 </div>
		 <div class="right">
			  <time  startTime='2015-12-17 15:05:00.0'></time>
			  <a class="get01"  ></a>
			  <p class='have'>剩100张</p>
			  <a class="detail"></a>
		 </div> 
	</div>
</section>

Js代码:

function reduceTime(){
	var Now = new Date("2015/12/18 14:53:21"),
	    reduceTime_ = function(){
	
		Now.setSeconds(Now.getSeconds()+1);
		$('time').each(function(){
			var End = $(this).attr('startTime');
			    End= new Date(temp);
			var t =End.getTime() - Now.getTime();
			if(t>0){
				$(this).parent().find('.get01,.have').css('visibility','hidden');
				var d = 0, h = 0, m = 0, s = 0, arr = [];
				if(t>=0){
					d=Math.floor(t/1000/60/60/24);
					h=Math.floor(((t/1000/60/60)%24)-(d*24));
					m=Math.floor(t/1000/60%60);
					s=Math.floor(t/1000%60);
					h += d*24;
					arr=[d==0 ? '' : (d+'天'),h==0 ? '' : (h+'小时'),(m<10 ? ('0'+m) : m) +':',s<10 ? ('0'+s) : s];
				}
				if(parseInt(arr[0])>0||parseInt(arr[1])>0){
				   arr.splice(2,2);
				}
				$(this).html('<span style="color:#db5252;font-size:16px">倒计时</span> <br/>'+arr.join(''));						
			}else{
				$(this).parent().find('.get01,.have').css('visibility','visible');
				$(this).remove();
			}
		}) 
	};
	reduceTime_();
	//轮询执行 抢购倒计时
	setInterval(reduceTime_,1000);		
}

reduceTime();

二:提交测试

由于功能比较简单,整个前端交互很快就顺利完成,使用自己的小米4手机自测无误之后,就直接把页面提交后台开发人员,自己埋头继续研究其它项目去了。

次日开发兄弟表示已经完成后台开发,而且使用他的三星手机测试成功。于是我简单地参与测了一下,确认成功之后,就把项目提交测试。坐等测试结果。我们的测试部门全是土豪,几乎都是水果6的手机,结果我们屁股还没坐热,测试就反馈过来,苹果手机里面根本没有倒计时功能,你们确定你们开发了这个功能吗?当时我们就震惊的掏出自己的屌丝机重新访问了一下测试地址,确定是有倒计时,然后让测试mm清空微信缓存再重新刷新下,可是最终他们也没看到倒计时,一个赤裸裸的操作系统bug,安卓正常,ios出错,而且这个bug直接切断了测试人员继续测试其它bug的去路。

三:bug分析、解决

拿到这个bug,我首先仔细审视了下自己的这段前端代码,代码本身逻辑应该正确,毕竟安卓下能成功显示。先映入自己脑海的是,后台传入的时间是否跟我自己期待的一致,带着这个疑问,在代码的中间插入了alert,在手机端无法使用console,转而使用弹窗模式来提示具体的节点信息。果然,拿到的服务器数据格式是:2015-12-18 12:00:00.0,项目是跑在Apach Tomcat里面,我一般在前端使用new Data(),传入参数的时候习惯使用2015/12/18 12:00:00格式,于是通过查阅相关资料-Javascript invalid date in iOS/Android 2.2发现在安卓2.2以及ios系统下面,用2015-12-18这种横线模式初始化日期是会直接报invalid date的错误,Rhino开发也同样存在这个问题。而自己使用的小米4以及同事的三星手机刚好都是安卓4.x.x版本,已经升级到可以包容这种横线日期格式,不会报错;ios系统则继续保持严谨的格式,所以直接报错,倒计时无法出现。定位到问题就简单了,直接startTime = startTime.replace(/\-/g,'/');直接把横线替换成斜杠,然后再跑一遍应该就OK了。结果改成试验的时候还是报错invalid date,后来仔细观察发现2015-12-18 12:00:00.0,后面多了一个小数点跟一个数字,从这个结果上看,这个数字估计是百毫秒单位,因为1000毫秒=1秒,原来安卓4.xx系统把百毫秒也合并进来了,最后,把后面的小数点和数字去掉之后,ios终于能正常出现倒计时了。

四:小结

不得不佩服IOS在代码方面的严谨性,也佩服安卓在不同版本升级中的容错性越来越好,各有各的好,多多学习,多多积累!

五:参考资料:Javascript invalid date in iOS/Android 2.2  苹果系统时间格式问题



码字很辛苦,转载请注明来自tuy博客《偶遇IOS8和IOS9中Javascript的Date问题》

评论

  1. XIONGMAO #1

    :evil: 都查到 stackoverflow 上去了,阅读广泛啊

    回复
    2016-03-8
    • admin
      admin

      :razz: 胸哥

      回复
      2016-03-8