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

React伦敦公交实时应用:计算发车时间差显示分钟数遇NaN问题求助

解决伦敦公交实时发车时间转换为剩余分钟数的问题

看起来你遇到的NaN问题大概率是因为时间处理时没有正确结合日期和时区导致的——expected_departure_estimate只有时分信息,直接转Date对象会因为缺少日期或者时区不匹配,计算差值时出现无效值。下面是具体的解决思路和修改后的代码:

第一步:编写计算剩余分钟数的工具函数

我们需要把API返回的伦敦当地时间(比如"14:49")和当前伦敦时间做对比,计算差值。注意要强制使用伦敦时区,避免本地时区干扰:

const calculateRemainingMinutes = (departureTimeStr) => {
  // 解析时分
  const [hours, minutes] = departureTimeStr.split(':').map(Number);
  
  // 获取当前伦敦时间的Date对象
  const nowLondon = new Date(new Date().toLocaleString('en-US', { timeZone: 'Europe/London' }));
  // 构建当天的预计发车时间(伦敦时区)
  const departureTime = new Date(nowLondon);
  departureTime.setHours(hours, minutes, 0, 0);
  
  // 兜底处理:如果预计时间已经过去(比如当前15:00,发车时间14:49),默认按次日时间计算
  if (departureTime < nowLondon) {
    departureTime.setDate(departureTime.getDate() + 1);
  }
  
  // 计算差值(毫秒转分钟)
  const diffMs = departureTime - nowLondon;
  const diffMins = Math.round(diffMs / (1000 * 60));
  
  // 优化显示:小于1分钟显示"Due",否则显示"X mins"
  return diffMins <= 0 ? 'Due' : `${diffMins} mins`;
};

第二步:修改组件代码使用这个函数

在你的BusInfo组件中,调用上面的函数替换原来的departure.best_departure_estimate:

const BusInfo = ({ busStopInfo }) => { 
  const [busList, setBusList] = useState({}); 
  const [isError, setIsError] = useState(false); 

  // 新增工具函数
  const calculateRemainingMinutes = (departureTimeStr) => {
    const [hours, minutes] = departureTimeStr.split(':').map(Number);
    const nowLondon = new Date(new Date().toLocaleString('en-US', { timeZone: 'Europe/London' }));
    const departureTime = new Date(nowLondon);
    departureTime.setHours(hours, minutes, 0, 0);
    
    if (departureTime < nowLondon) {
      departureTime.setDate(departureTime.getDate() + 1);
    }
    
    const diffMs = departureTime - nowLondon;
    const diffMins = Math.round(diffMs / (1000 * 60));
    
    return diffMins <= 0 ? 'Due' : `${diffMins} mins`;
  };

  useEffect(() => { 
    const getBusTimes = async () => { 
      try { 
        const result = await axios(`${url}/${busStopInfo.atcocode}/live.json`, { 
          params: { 
            app_id: apiId, 
            app_key: apiKey, 
            group: "no", 
            limit: 10, 
            nextbuses: "yes", 
          }, 
        }); 
        setBusList(result.data.departures); 
        console.log(result.data.departures); 
      } catch (error) { 
        setIsError(true); 
      } 
    }; 
    getBusTimes(); 
  }, [busStopInfo.atcocode]); 

  // 新增加载/错误状态提示(提升用户体验)
  if (!busList.all) {
    return <div>Loading bus times...</div>;
  }

  if (isError) {
    return <div>Failed to load bus times. Please try again later.</div>;
  }

  return ( 
    <div> 
      <h5>{busStopInfo.name}</h5> 
      <p>{busStopInfo.description}</p> 
      {busList.all.map((departure, i) => ( 
        <li style={{ listStyleType: "none" }} key={i}> 
          <h6> 
            <span className={styles.busItem}>{departure.line}</span> 
            <small>towards</small>{" "} 
            {departure.direction} 
            {/* 替换成计算后的剩余分钟数 */}
            <span> {calculateRemainingMinutes(departure.expected_departure_estimate)}</span>
          </h6> 
        </li> 
      ))} 
    </div> 
  ); 
}; 
export default BusInfo; 

关键注意点

  • 时区处理:必须强制使用伦敦时区(Europe/London),因为transportAPI返回的是伦敦当地时间,避免你的本地时区(比如北京时间)导致计算错误。
  • 日期补全:把API返回的时分和当前伦敦日期结合,避免Date对象默认使用本地日期或错误的日期。
  • 边界情况:当差值小于等于0时,显示"Due"(表示即将发车),更符合公交应用的用户习惯。

这样修改后,应该就能正常显示剩余分钟数,不会再出现NaN了。

内容的提问来源于stack exchange,提问作者Asher

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 06:52:29