倒计时代码(兼容ios)
beforeDestroy(){ //页面销毁前清除定时器
clearInterval(this.countTimes)
}
methods:{
//方案一:先处理成ios和安卓均可转换的时间格式,再统一处理
timer(){
let u = navigator.userAgent;
let iosPreTime=item.livedate.split(/[- :]/) //直接去除时间格式里的- :,生成数组后,再统一处理数组转换为毫秒数时间
let preTime = new Date(iosPreTime[0],iosPreTime[1]-1,iosPreTime[2],iosPreTime[3],iosPreTime[4],iosPreTime[5]).getTime()
this.countTimes=setInterval(()=>{
let nowTime = new Date().getTime();
let obj = null;
if(preTime - nowTime > 0){
let time = (preTime - nowTime) / 1000;
let day = parseInt(time / (60 * 60 * 24));
let hou = parseInt(time % (60 * 60 * 24) / 3600);
let min = parseInt(time % (60 * 60 * 24) % 3600 / 60);
let sec = parseInt(time % (60 * 60 * 24) % 3600 % 60);
obj = {
day: day<10?'0'+day:day,
hou: hou<10?'0'+hou:hou,
min: min<10?'0'+min:min,
sec: sec<10?'0'+sec:sec
};
this.timing = obj.day + '天' + obj.hou + '时' + obj.min + '分' + obj.sec + '秒';
} else {
obj = {day:'00',hou:'00',min:'00',sec:'00'};
clearInterval(this.countTimes)
}
},1000)
}
//方案二:先处理成ios和安卓均可转换的时间格式,再统一处理
let iosPreTime=item.livedate.replace(/-/g,'/') //因为ios只能处理 / 形式的,安卓 - 和 / 形式的均可处理,则将格式里的 - 统一替换成 / 即可
let preTime = new Date(iosPreTime).getTime()
//方案三:先区分是ios端还是安卓端,再分别处理
timer(){
let u = navigator.userAgent;
if(!!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)){ //ios端
//ios端与安卓端时间格式不同,需做兼容处理。(ios不识别2020-02-02 20:20:20时间格式,但ios识别2020/02/02 20:20:20;安卓两种格式均识别)
let iosPreTime=item.livedate.replace(/-/g,'/') //在ios端将时间格式里的 - 替换成 / 供ios端处理
let preTime = new Date(iosPreTime).getTime()
}else{ //非ios端 --- 安卓端,pc端
let preTime = new Date(this.predate).getTime() //注意后端接口返回的predate格式应为 2020-02-02 20:20:20或2020/02/02 20:20:20。2020-20-20格式需做以上兼容处理,2020/20/20不需要处理
}
this.countTimes=setInterval(()=>{
let nowTime = new Date().getTime();
let obj = null;
if(preTime - nowTime > 0){
let time = (preTime - nowTime) / 1000;
let day = parseInt(time / (60 * 60 * 24));
let hou = parseInt(time % (60 * 60 * 24) / 3600);
let min = parseInt(time % (60 * 60 * 24) % 3600 / 60);
let sec = parseInt(time % (60 * 60 * 24) % 3600 % 60);
obj = {
day: day<10?'0'+day:day,
hou: hou<10?'0'+hou:hou,
min: min<10?'0'+min:min,
sec: sec<10?'0'+sec:sec
};
this.timing= obj.day + '天' + obj.hou + '时' + obj.min + '分' + obj.sec + '秒';
} else {
obj = {day:'00',hou:'00',min:'00',sec:'00'};
clearInterval(this.countTimes)
}
},1000)
},
}
一般页面的定时器的使用及清除
setInterval定时器:请保证在页面销毁前清除该定时器,如在beforeDestroy生命周期里清除定时器
setTimeout定时器:该定时器只使用一次,为避免占用内存,请使用后即清除
如let times=setTimeout(()=>{
console.log("定时器触发了")
clearTimeout(times) //执行完相关语句后即可清除定时器
})
使用了keepAlive的页面的定时器的使用及清除
因为keepAlive的机制,再次进入缓存页面,生命周期会发生改变(见https://www.cnblogs.com/huihuihero/p/11905439.html),created及mounted生命周期将不再执行。数据不会更新。
若定时器触发放在了created或mounted生命周期里。则再次进入keepAlive页面,因created及mounted生命周期不再执行,定时器也将不再执行。
若想在每次进入keepAlive的页面依旧触发定时器,以及离开此页面清除定时器。则:
定时器触发放在activated生命周期里,定时器清除放在deactivated生命周期里即可。
如
activated(){
this.times=setInterval(()=>{
console.log("定时器触发了")
})
}
deactivated(){
clearInterval(this.times) //清除定时器
}
ios端与安卓端的时间兼容问题
主要问题是:ios端不支持2020-02-02 20:20:20这种以-分割的时间格式。ios端仅支持2020/02/02 20:20:20这种以/分割的时间格式。而安卓端及pc端这两种格式的均支持。
解决办法:
1、判断如果是ios端则将时间格式转换成以/分割的形式。
如 let time='2020-02-02 20:20:20'.replace(/-/g,'/') //返回结果:"2020/02/02 20:20:20"
let preTime = new Date(time).getTime() //返回结果: 毫秒数:1580646020000
2、将时间格式转化成数组格式再去转换成毫秒数。
如 let time='2020-02-02 20:20:20'.split(/[- :]/) //返回结果:["2020", "02", "02", "20", "20", "20"]
let preTime = new Date(time[0],time[1]-1,time[2],time[3],time[4],time[5]).getTime() //返回结果: 毫秒数:1580646020000
时区问题导致的倒计时不准确
js获取到的中国区用户的本地时间和美国区的本地时间是不同的,因为这两个地方的时区是不同的。
如果不做处理的话,去算倒计时会导致,美国区域的倒计时比中国区域的多几到十几个小时。所以如果有这方面的需求可以做一下兼容
//将世界时间均转为北京时间,时间戳形式
getBeijingtime() {
//获得当前运行环境时间
let d = new Date();
let currentDate = new Date();
let tmpHours = currentDate.getHours();
//算得时区
var time_zone = -d.getTimezoneOffset() / 60;
if (time_zone < 0) {
time_zone = Math.abs(time_zone) + 8; currentDate.setHours(tmpHours + time_zone);
} else {
time_zone -= 8; currentDate.setHours(tmpHours - time_zone);
}
return currentDate.getTime()
},
let nowTime = new Date().getTime()
替换为
let nowTime = this.getBeijingtime()
转换时间格式,将时间戳转换为固定格式时间
transDate(dateNum){
const date=new Date(dateNum)
let Y=date.getFullYear()
let M=date.getMonth()+1
M=M<10?('0'+M):M
let D=date.getDate()
D=D<10?('0'+D):D
let h=date.getHours()
h=h<10?('0'+h):h
let m=date.getMinutes()
m=m<10?('0'+m):m
let s=date.getSeconds()
s=s<10?('0'+s):s
return `${Y}-${M}-${D} ${h}:${m}:${s}`
},
将北京时间转换为全球各个地区的时间,应用场景见下图
//指定时间dateNum值格式:2021-07-01 10:30:00
transLocalDate(dateNum){
let dateNum2=dateNum.replace(/-/g,'/') //适配ios时间格式
const bjTime=new Date(dateNum2).getTime() //指定时间对应的北京时间的时间戳
const utcTime=bjTime+(-480*60*1000) //指定时间对应的UTC时间的时间戳
const localOffset=new Date().getTimezoneOffset()*60*1000 //当地时间与UTC偏移量,单位:ms
const localTime=utcTime-localOffset //指定时间对应的当地时间的时间戳
const date=new Date(localTime)
let Y=date.getFullYear()
let M=date.getMonth()+1
M=M<10?('0'+M):M
let D=date.getDate()
D=D<10?('0'+D):D
let h=date.getHours()
h=h<10?('0'+h):h
let m=date.getMinutes()
m=m<10?('0'+m):m
let s=date.getSeconds()
s=s<10?('0'+s):s
return `${Y}-${M}-${D} ${h}:${m}:${s}`
},
解决格林尼治时间在ios端和android端的兼容问题
格林尼治时间格式:2019-03-05T09:02:24.000+0000
android端:
new Date("2019-03-05T09:02:24.000+0000") 可正常转换。
new Date("2019-03-05T09:02:24.000+0000".substr(0,19)) 转换出来的时间会早8个小时
ios端:
new Date("2019-03-05T09:02:24.000+0000") 输出为NaN,不可用。
new Date("2019-03-05T09:02:24.000+0000".substr(0,19)) 可正常转换
故通过判断是否是ios端,再选择转换方式。具体代码如下:
transDate(dateNum){
let u = navigator.userAgent;
let date=null;
if (!!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)) { //ios端
date=new Date(dateNum.substr(0,19)) //截取前19位后再转换
}else{ //非ios端
date=new Date(dateNum) //不截取,正常转换
}
let Y=date.getFullYear()
let M=date.getMonth()+1
M=M<10?('0'+M):M
let D=date.getDate()
D=D<10?('0'+D):D
let h=date.getHours()
h=h<10?('0'+h):h
let m=date.getMinutes()
m=m<10?('0'+m):m
let s=date.getSeconds()
s=s<10?('0'+s):s
return `${Y}-${M}-${D} ${h}:${m}:${s}`
},
【更方便的方法:】
transDate(dateNum){
let date=new Date(dateNum) ? new Date(dateNum) : new Date(dateNum.substr(0,19));
let Y=date.getFullYear()
let M=date.getMonth()+1
M=M<10?('0'+M):M
let D=date.getDate()
D=D<10?('0'+D):D
let h=date.getHours()
h=h<10?('0'+h):h
let m=date.getMinutes()
m=m<10?('0'+m):m
let s=date.getSeconds()
s=s<10?('0'+s):s
return `${Y}-${M}-${D} ${h}:${m}:${s}`
},
通过给定时间判断此时间是属于今天、昨天、还是前天
//判断今天、昨天、前天
judgeDateOfWhichDay(time){
let theTime=new Date(time).getTime() //此处将 需要传入的时间 转换为时间戳形式
let twentyFourHours=24*60*60*1000 //24小时间隔时间戳
let todayNowTime=new Date() //截止到今日现在的时间
let todayY=todayNowTime.getFullYear()
let todayM=todayNowTime.getMonth()+1
let todayD=todayNowTime.getDate()
let todayDate=`${todayY}/${todayM}/${todayD}` //截止今日凌晨的时间:年/月/日
//注:为兼容iOS端,这里建议使用 年/月/日,而非 年-月-日,至于原因上文有提到iOS端和Android端的差异
let todayZeroPointTime=new Date(todayDate).getTime() //截止今日凌晨的时间戳
let yesterdayZeroPointTime=todayZeroPointTime-twentyFourHours //截止昨日凌晨的时间戳
let lastYesterdayZeroPointTime=todayZeroPointTime-twentyFourHours*2 //截止前日凌晨的时间戳
//判断时间戳属于的时间段
if(theTime>=todayZeroPointTime){ //今天
return "today"
}else if(theTime<todayZeroPointTime&&theTime>=yesterdayZeroPointTime){ //昨天
return "yesterday"
}else if(theTime<yesterdayZeroPointTime&&theTime>=lastYesterdayZeroPointTime){ //前天
return "lastYesterday"
}else{ //更久之前
return "longer"
}
},
转换时间为多种情况的可展示信息如:刚刚、xx分钟前、今天xxx、昨天xxx、前天xxx等
transDateToShowText(dateNum){
const date = new Date(dateNum)
let Y = date.getFullYear()
let M = date.getMonth()+1
M = M<10?('0'+M):M
let D = date.getDate()
D = D<10?('0'+D):D
let h = date.getHours()
let inith = h
h = h<10?('0'+h):h
let m = date.getMinutes()
let initm = m
m = m<10?('0'+m):m
let s = date.getSeconds()
s = s<10?('0'+s):s
const nowDate = new Date() //获取今天时间信息
let initnh = nowDate.getHours()
let initnm = nowDate.getMinutes()
let dayJudgeRes = judgeDateOfWhichDay(dateNum)
if(dayJudgeRes=="today"){ //评论时间为今日内
let nowMinCount = initnh*60+initnm //该评论时间距离今日0点的分钟数
let commentMinCount = inith*60+initm //现在时间距离今日0点的分钟数
let text = ``
if(nowMinCount - commentMinCount <=1){
text = `刚刚`
}else if(nowMinCount - commentMinCount>1 && nowMinCount - commentMinCount<60){
text = `${nowMinCount - commentMinCount}分钟前`
}else{
text = `今天 ${h}:${m}`;
}
return text
}else if(dayJudgeRes=="yesterday"){
return `昨天 ${h}:${m}`;
}else if(dayJudgeRes=="lastYesterday"){
return `前天 ${h}:${m}`;
}else{
return `${Y}.${M}.${D} ${h}:${m}`
}
}