js中相关时间业务的问题,如何解决?

自己定义一个保险到期时间 例如2022-12-21 10:45:45 需要计算到时分秒

1.有保险到期时间,需要判断当前时间是否超出了保险到期时间,超出了的话,显示【投保】
2.有保险到期时间,需要判断当前时间是否距离保险到期时间小于等于9个月,符合的话显示【续保】,否则【不显示】

阅读 3.2k
8 个回答
let time = '2022-12-21 10:45:45' // 保险到期时时间
if (time) {
  let endTime = new Date(time) // 保险到期时间
  let nowTime = new Date() // 当前时间

  // 会自动转时间戳判断
  if (endTime < nowTime) {
    console.log('投保');
  } else {
    // 按每月30天算
    if((endTime - nowTime) <= (86400000 * 9 * 30)) {
      // 当前时间距离保险到期时间小于等于9个月
      console.log('续保');
    } else {
      console.log('不显示');
    }
  }
}

解决方法:
1.自己封装时间方法,来判断时间业务逻辑;
2.引用第三方库,如:moment,dayjs,date-fns

业务逻辑处理:
1.当前时间减去保险到期时间,超出显示【投保】
2.当前时间减去保险到期时间是否超出9个月,未超出显示【续保】

计算天数差
你可以参考这个代码段,然后计算出两个日期之间的天数差,然后再根据每月有多少天,来计算月数差,从而得到是否超过9个月。
当然也可以看看这个代码段:
计算月份差

const getStatusByDate = (time, month) => {
    time = time.replaceAll('-', '/') // 兼容ios
    let end = new Date(time)
    let endTime = end.getTime() // 保险到期时间毫秒
    let nowTime = new Date().getTime() // 当前时间毫秒
    let nineMonthBefore = new Date(time)
    let nineYear = nineMonthBefore.getFullYear()
    nineMonthBefore.setMonth(nineMonthBefore.getMonth() - month)
    let nineMonth = nineMonthBefore.getMonth()
    // 假设保险到期时间为2022年11月,日期大于了2月最后一天,则将时间设置到2月最后一天  2022-11-29 ---> 2022-02-28
    nineMonthBefore.getDate() != end.getDate() && nineMonthBefore.setDate(new Date(nineYear, nineMonth, 0).getDate())
    console.log(nineMonthBefore);
    nineMonthBefore = nineMonthBefore.getTime() // 距离保险到期时间的九个月前的毫秒数
    return nowTime > endTime ? '【投保】' : nowTime >= nineMonthBefore && nowTime <= endTime ? '【续保】' : ''
}
console.log(getStatusByDate('2022-12-21 10:45:45', 9))
const insuranceExpirationDate = new Date('2022-12-21 10:45:45');
const currentDate = new Date();

if (currentDate > insuranceExpirationDate) {
  console.log('显示【投保】');
} else {
  const monthsUntilExpiration = monthsUntil(insuranceExpirationDate, currentDate);
  if (monthsUntilExpiration <= 9) {
    console.log('显示【续保】');
  } else {
    console.log('不显示');
  }
}

function monthsUntil(expirationDate, currentDate) {
  // 计算保险到期时间和当前时间之间的月数
  const months = (expirationDate.getFullYear() - currentDate.getFullYear()) * 12;
  months -= currentDate.getMonth() + 1;
  months += expirationDate.getMonth();
  return months <= 0 ? 0 : months;
}

基础的功能就不要引入库什么的了,一来是项目会太臃肿,二来是容易干不完活。直接手搓一段就好了,希望能帮到你。

代码逻辑不难,像 2022-12-21 10:45:45 这么标准的时间格式,直接 new Date(s) 就能封装成 Date 对象。而 Date 对象可以直接使用加减运算,得到以毫秒为单位的时间差。所以只需要进行简单的计算很容易得到你需要的结果。

但是这里有有一个问题:9 个月是怎么算的?是按每个月 30 天来算的 9 个月,还是自然的 9 个月。如果是自然的 9 个月,在某些特殊日期,比如 12 月 31 日之后的 9 个月正好是 9 月,但 9 月没有 31 号,那是否算成 9 月 30 日呢?或者返过来说,11 月 30 日的 9 个月前正好是 2 月,但 2 月没有 30 号,是否算成 2 月 28 日?

如果按每月 30 天来算,那自然是最好算的。但如果是后者,算起来需要考虑一些细节。

Date 对象本身是可以做简单的计算的,比如

const d = new Date("2022-10-11");
d.setMonth(d.getMonth() + 9);
console.log(d.toISOString());  // 2023-07-11T00:00:00.000Z

但是遇到刚才说的那种情况,你看:

const d1 = new Date("2022-12-31");
d1.setMonth(d1.getMonth() + 9);
console.log(d1.toISOString());  // 2023-10-01T00:00:00.000Z

const d2 = new Date("2022-11-30");
d2.setMonth(d2.getMonth() - 9);
console.log(d2.toISOString());  // 2022-03-02T00:00:00.000Z

它会把“日”顺延,如果这个月只有 28 天,那原本的 30 号就会变成下个月的 2 号。如果本来是想舍去多余的日子变成 2 月 28 号的话,当月号数是否大于目标月的最后一天……当然写一段代码来判断是不会有问题的,就是累。

这种情况下我还是建议直接用库,比如用 dayjs:

console.log(
    dayjs("2022-12-31 14:23:32")
        .add(9, "month")
        .format("YYYY-MM-DD HH:mm:ss")
);  // 2023-09-30 14:23:32

console.log(
    dayjs("2022-11-30 14:23:32")
        .add(-9, "month")
        .format("YYYY-MM-DD HH:mm:ss")
);  // 2022-02-28 14:23:32

还是补个手写的解决办法,其实也不是很难

function addMonth(date, m) {
    const d = date.getDate();
    date.setMonth(date.getMonth() + m);
    if (date.getDate() !== d) {
        date.setDate(0);
    }
    return date;
}

const d1 = new Date("2022-12-31");
addMonth(d1, 9)
console.log(d1.toISOString());  // 2023-09-30T00:00:00.000Z

const d2 = new Date("2022-11-30");
addMonth(d2, -9)
console.log(d2.toISOString());  // 2022-02-28T00:00:00.000Z
function getInsuranceExpireTips(time) {
      let date = new Date()
      let date1 = new Date(time)
      date1.setMonth(date1.getMonth() + 9)

      if (date - Date.parse(time) < 0) {
        return '不显示'
      }

      return date - date1 > 0 ? '投保' : '续保'
    }
    getInsuranceExpireTips('2022-12-21 10:45:45')

vue 的话,你可以放入计算属性,具体方法就是他们上面的哪些。

当前时间放入 data 、 reactive 中,然后整个定时器动态赋值,修改之后会触发计算属性重复计算。

以一楼「以琳」代码为例,

// let nowTime = new Date() // 当前时间这里需要用一个响应式
let nowTime = this.nowTime

这样改动之后,也可以显示倒计时之类的

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏