2022-07-20 工作记录--React-js将时间戳转换成“天时分秒” + “天时分秒”的倒计时

一、实现效果

请添加图片描述

假如后端返了两个数据:当前时间13位时间戳currentTimestamp到期时间13位时间戳expireTimestamp,想实现“还有多久到期的时间”的倒计时,即:到期时间与当前时间之间的时间差以“天时分秒”的形式进行倒计时,如下动图:

请添加图片描述

二、实现方式

第一步、封装方法——js将时间戳转换成“天时分秒”

请添加图片描述

utils.js

1、写法一 ⭐️
/** 
1、js获取 倒计时 天时分秒
通过时间戳的方式来 
 let d =  parseInt(dec / 60 / 60 / 24); // 天
 let h =  parseInt(dec / 60 / 60 % 24); // 时
 let m =  parseInt(dec / 60 % 60); // 分
 let s =  parseInt(dec % 60); // 秒
 2、参数分析:
 @params {Num} inputTime: 需要转换成 天时分秒 的 13位时间戳
 @params {Boolean} isPop: 便于实现两种返回结果:true -> `${d}天${h}小时${m}分${s}秒` ; false -> 包含天时分秒的finalDateObj对象
 */
export function timestampFormatter(inputTime, isPop = false) {
  // 最终时间结果对象
  const finalDateObj = {
    d: null, // 天
    h: null, // 小时
    m: null, // 分钟
    s: null, // 秒
  }
  
  // 剩余时间总的毫秒数 除以 1000 变为总秒数(时间戳为13位 需要除以1000,为10位 则不需要)
  let dec = inputTime / 1000;
  
  if (dec <= 0) {
    dec = 0;
  }
  
  // 得到天 格式化成前缀加零的样式
  let d = parseInt(dec / 60 / 60 / 24);
  d = d < 10 ? '0' + d : d;
  // 得到小时 格式化成前缀加零的样式
  let h = parseInt(dec / 60 / 60 % 24);
  h = h < 10 ? '0' + h : h;
  // 得到分钟 格式化成前缀加零的样式
  let m = parseInt(dec / 60 % 60);
  m = m < 10 ? '0' + m : m;
  // 得到秒 格式化成前缀加零的样式
  let s = parseInt(dec % 60);
  s = s < 10 ? '0' + s : s;

  finalDateObj.d = d;
  finalDateObj.h = h;
  finalDateObj.m = m;
  finalDateObj.s = s;
  
  // 两种返回结果
  return isPop ? `${d}${h}小时${m}${s}` : finalDateObj;
}
2、写法二 ⭐️
/** 
1、js获取 倒计时 天时分秒
通过时间戳的方式来 
 let d =  Math.trunc(dec / 3600 / 24); // 天
 let h =  Math.trunc(dec % (24 * 3600) / 3600); // 时
 let m =  Math.trunc(dec % 3600 / 60); // 分
 let s =  Math.trunc(dec % 3600 % 60); // 秒
 2、参数分析:
 @params {Num} inputTime: 需要转换成 天时分秒 的 13位时间戳
 @params {Boolean} isPop: 便于实现两种返回结果:true -> `${d}天${h}小时${m}分${s}秒` ; false -> 包含天时分秒的finalDateObj对象
 */
export function timestampFormatter(inputTime, isPop = false) {
  // 最终时间结果对象
  const finalDateObj = {
    d: null, // 天
    h: null, // 小时
    m: null, // 分钟
    s: null, // 秒
  }
  
  // 剩余时间总的毫秒数 除以 1000 变为总秒数(时间戳为13位 需要除以1000,为10位 则不需要)
  let dec = inputTime / 1000;
  
  if (dec <= 0) {
    dec = 0;
  }
  
  // 得到天 格式化成前缀加零的样式
  let d = Math.trunc(dec / 3600 / 24); 
  d = d < 10 ? '0' + d : d;
  // 得到小时 格式化成前缀加零的样式
  let h = Math.trunc(dec % (24 * 3600) / 3600);
  h = h < 10 ? '0' + h : h;
  // 得到分钟 格式化成前缀加零的样式
  let m = Math.trunc(dec % 3600 / 60);
  m = m < 10 ? '0' + m : m;
  // 得到秒 格式化成前缀加零的样式
  let s = Math.trunc(dec % 3600 % 60);
  s = s < 10 ? '0' + s : s;

  finalDateObj.d = d;
  finalDateObj.h = h;
  finalDateObj.m = m;
  finalDateObj.s = s;
  
  // 两种返回结果
  return isPop ? `${d}${h}小时${m}${s}` : finalDateObj;
}

第二步、实现“天时分秒”的倒计时

请添加图片描述

实现思路:⭐️

  • 1、先在state里定义两个属性:
    • finalDate——倒计时初始值(初始化为字符串 “00天00时00分00秒”),
    • canMountDown——判断是否开启定时器。
  • 2、初始化定时器timernull
  • 3、定义一个方法FunTimer(里面写一个setInterval定时器timer,装实现倒计时的代码(我封装成了一个函数updateTime)),
  • 4、在componentDidMount里进行判断:
    • canMountDowntrue,就调用方法FunTimer,并把canMountDown置为false
    • canMountDownfalse,就把timer定时器关了,并把canMountDown置为true
  • 5、编写函数updateTime:【实现倒计时的代码】
    • 第1步、获取到过期时间;
    • 第2步、获取到当前时间的时间戳(后端返的值);
    • 第2步、手动把获取到的当前时间 隔一秒加1s 得到新的当前时间,赋值给store里的当前时间的时间戳;
    • 第3步、 引入上面封装好的方法timestampFormatterjs将时间戳转换成“天时分秒”),将到期时间与新的当前时间的差值传进去,获取到对应的“天时年分”,并赋值到state里的finalDate
    • 第4步、将state里的finalDate写到html对应位置 就大功告成啦~
  • 6、在componentWillUnmount里关闭定时器

tasksDetails.jsx

import React,{Component} from 'react';
import { timestampFormatter } from '@src/utils/utils'; // 引入上面封装好的方法——`js`将时间戳转换成“天时分秒”
import store from '@src/utils/store'; // 引入store【store相关的是我项目接口相关的内容和公用方法,小萝卜儿们可根据实际情况处理】

class CountDown extends Component{

	// 1、初始化state
  	state = { 
    	canCountDown: true, // 判断是否开启定时器
   		finalDate: '00天00小时00分00秒', // 倒计时初始值
  	}
  	
  	// 2、初始化定时器
    timer = null; 

	// 自定义当前时间的时间戳
	// currentTimestamp = null;

	async componentDidMount() {
		await store.getQueryTasks(); // 调用接口-获取到任务列表里的数据

		// 初始化当前时间的时间戳(初始值取后端返滴数据: store?.currentTimestamp)【注意: currentTimestamp一定要记得*1转换成数值型哟】
		// this.currentTimestamp = store?.currentTimestamp * 1;

		this.handleCountDownLogic(); // 处理倒计时总逻辑【是否开启倒计时处理】
  	}

	// 4、处理倒计时总逻辑【是否开启倒计时处理】
    handleCountDownLogic = () => {
		if (this.state.canCountDown) {
      		this.setState({ canCountDown: false })
      		this.FunTimer(); // 调用函数-倒计时
    	} else {
      		this.setState({ canCountDown: true })
      		clearInterval(this.timer); // 关闭定时器
    	}
	}
  	
    // 6、在componentWillUnmount里关闭定时器
	componentWillUnmount() {
    	clearInterval(this.timer); // 关闭定时器
  	}
  
   	// 3、封装函数-倒计时
  	FunTimer = () => {
    	this.timer = setInterval(() => {
      		// 想实现倒计时的代码就写在这里啦~【我单独封装了一个函数】
      		this.updateTime();
    	}, 1000)
  	}

	// 5、更新时间
  	updateTime = () => {
    	const expireTimestamp = 1660970113000; // 到期时间【实际情况时 由后台返回,这儿写死只是做个测试】
    	const { currentTimestamp } = store; // 获取到后端返的当前时间的时间戳
    	/** 手动把获取到的当前时间 隔一秒加1s,并更新store里的当前时间的时间戳【注意: currentTimestamp一定要记得*1转换成数值型哟】*/
    	// this.currentTimestamp += 1000;
    	store.setCurrentTimestamp(currentTimestamp * 1 + 1000);
    	/** 计算得到需要倒计时的时间戳 */
    	// const countDownTimestamp = expireTimestamp * 1 - this.currentTimestamp * 1;
    	const countDownTimestamp = expireTimestamp * 1 - currentTimestamp * 1;
    	/** 调用上面封装的方法timestampFormatter,计算到倒计时的展示结果,并state赋值,方便html里进行展示 */
    	const result = timestampFormatter(countDownTimestamp, true);
    	this.setState({
      		finalDate: result,
    	})
    	
		/** 倒计时的时间戳小于0,则刷新任务列表数据、关闭定时器 */
        if (countDownTimestamp < 0) {
            console.log('倒计时小于0咯~');
            clearInterval(this.timer); // 关闭定时器
            this.timer = null; // 将定时器归置为null
            
            // 根据自己需求进行操作
            store.getQueryTasks(); // 刷新任务列表数据
        }
  	}
    
    render(){
	    return(
		    <div>
		       	 倒计时:{this.state.finalDate}
		   	</div>
	   	)
	}
}
export default CountDown;

store/index.js:【就是与接口相关滴代码,小萝卜儿们根据自己平时的思路来即可哦~

import { makeAutoObservable } from 'mobx';
import API from '../api/index';

const store = makeAutoObservable({
  /** 任务列表 */
  tasksList: {},
  /** 设置任务列表数据 */
  setTasksList(data) {
    this.tasksList = data;
  },
  
  /** 当前时间的时间戳 */
  currentTimestamp: null,
  /** 设置当前时间的时间戳 */
  setCurrentTimestamp(data) {
  	this.currentTimestamp = data;
  }

  /** 查询任务列表 */
  async getQueryTasks() {
    const { data, success } = await API.queryTasks(); // 调用接口
    if (data && success) {
      this.setTasksList(data); // 设置任务列表数据
      
      // currentTime: 当前时间的时间戳
      const { currentTime } = data;
      this.setCurrentTimestamp(currentTime);
    }
  },

});
export default store;

请添加图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小呀小萝卜儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值