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
相关产品推荐
相关产品推荐

