You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用moment实现LocalStorage存储值当日午夜后过期

完全可以用moment实现需求,现有逻辑的核心问题是仅存储了YYYY-MM-DD格式的日期字符串,没有记录精确的过期时间节点,无法完成可靠的时间比对。

具体实现步骤

1. 改造按钮点击时的存储逻辑

点击按钮写入LocalStorage时,直接用moment计算出当日午夜的时间戳,和点击标记一起序列化后存储:

const setVarReservation = () => {
  // 计算当日结束(次日0点前1毫秒)的时间戳,作为过期节点
  const expireTimestamp = moment().endOf('day').valueOf();
  const storageData = {
    isClicked: true,
    expireAt: expireTimestamp
  };
  window.localStorage.setItem('alertToBeSetted', JSON.stringify(storageData));
};

moment().endOf('day')会自动获取当前用户本地时区下当日的最后一毫秒对应的时间对象,转成数值时间戳后,只要当前时间超过这个值,就代表已经过了当日午夜,标记失效。以20:00点击的场景为例,计算出的过期时间就是当日23:59:59.999,刚好覆盖后续到午夜的4小时,完全匹配需求。

2. 改造登录时的校验逻辑

在登录触发的saga中,通过时间戳数值比对判断标记是否过期,逻辑如下:

const checkButtonVisible = () => {
  const storageRaw = window.localStorage.getItem('alertToBeSetted');
  // 无存储标记,直接展示按钮
  if (!storageRaw) return showButton();

  const { expireAt } = JSON.parse(storageRaw);
  const currentTimestamp = Date.now();
  // 当前时间超过过期时间,清除存储、展示按钮
  if (currentTimestamp > expireAt) {
    window.localStorage.removeItem('alertToBeSetted');
    return showButton();
  }
  // 未过有效期,隐藏按钮
  return hideButton();
};
可选无依赖实现方案

如果不想引入moment,用原生JavaScript的Date对象也可以实现完全一致的效果,不需要额外依赖:

// 原生计算当日午夜时间戳
const getTodayMidnightTs = () => {
  const now = new Date();
  const midnight = new Date(
    now.getFullYear(),
    now.getMonth(),
    now.getDate() + 1, // 日期+1切到次日
    0, 0, 0 // 时分秒置为0,即次日0点
  );
  return midnight.getTime();
};
注意事项
  • 不要直接用日期字符串做大小比对,字符串按字典序比较在跨日、跨月、跨年场景下很容易出现判断错误,用数值型时间戳做比较是最稳妥的方案
  • 如果业务要求统一按指定时区(而非用户本地时区)计算午夜时间,给moment配置对应时区参数、或给原生Date计算加对应时区偏移即可
  • 如果存在用户长时间挂起页面不刷新的场景,可以加一个一次性定时器,在计算出的午夜时间点自动触发一次校验,避免页面不刷新就一直不展示按钮的问题

内容的提问来源于stack exchange,提问作者Levi D.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 23:18:17