使用Moment JS筛选当前营业场馆时返回错误数组的问题
问题
我尝试用筛选器找出当前正在营业的场馆,这个筛选器在营业时间内和刚结束营业后的短时间内正常,但到深夜时会错误返回结果。我用Moment JS对比当前时间和场馆的营业时间(开门、关门时间)。
数据对象格式
value = [ { "id" : "place_01", "name" : "Place One", "location" : "Location One", "hours" : [ {"day": "Sunday", "day_id": 0, "hours": "9:00 AM - 5:00 PM", "open": "9:00 AM", "close": "5:00 PM", "tags": "" }, {"day": "Monday", "day_id": 1, "hours": "9:00 AM - 5:00 PM", "open": "9:00 AM", "close": "5:00 PM", "tags": "" }, {"day": "Tuesday", "day_id": 2, "hours": "9:00 AM - 5:00 PM", "open": "9:00 AM", "close": "5:00 PM", "tags": "" }, {"day": "Wednesday", "day_id": 3, "hours": "9:00 AM - 5:00 PM", "open": "9:00 AM", "close": "5:00 PM", "tags": "" }, {"day": "Thursday", "day_id": 4, "hours": "9:00 AM - 5:00 PM", "open": "9:00 AM", "close": "5:00 PM", "tags": "" }, {"day": "Friday", "day_id": 5, "hours": "9:00 AM - 9:00 PM", "open": "9:00 AM", "close": "9:00 PM", "tags": "" }, {"day": "Saturday", "day_id": 6, "hours": "9:00 AM - 9:00 PM", "open": "9:00 AM", "close": "9:00 PM", "tags": "" } ] } ]
当前使用的筛选代码
let f1 = value.filter(item => item.hours.some((hour: { day_id: any; close: string; open: string; }) => hour.day_id == moment().format('d') && hour.open <= moment().format('LT') && hour.close >= moment().format('LT') ) );
我期望筛选器只在匹配当日day_id且当前时间处于开门、关门时间之间时返回结果,但深夜时段会错误返回结果,该怎么修正逻辑?
解决方案
问题出在直接比较字符串格式的时间:深夜的LT格式时间(如12:00 AM)会因字典序规则,被判定为小于上午时间(如9:00 AM),同时小于下午关门时间(如5:00 PM),导致两个比较条件同时成立,错误返回结果。
正确的做法是将时间转换为可准确比较的数值(当日总分钟数),而非直接对比字符串。
修正后的代码
// 获取当前时间的当日总分钟数(0-1439,从0点开始计算) const currentMinutes = moment().hours() * 60 + moment().minutes(); // 获取当前日期的day_id并转为数字 const currentDayId = parseInt(moment().format('d'), 10); let f1 = value.filter(item => item.hours.some(hour => { // 解析开门时间为Moment对象,转换为当日总分钟数 const openMinutes = moment(hour.open, 'h:mm A').hours() * 60 + moment(hour.open, 'h:mm A').minutes(); // 解析关门时间为Moment对象,转换为当日总分钟数 const closeMinutes = moment(hour.close, 'h:mm A').hours() * 60 + moment(hour.close, 'h:mm A').minutes(); // 匹配当日,且当前时间处于开门、关门时间区间内 return hour.day_id === currentDayId && currentMinutes >= openMinutes && currentMinutes <= closeMinutes; }) );
逻辑说明
- 将所有时间转换为当日总分钟数:比如9:00 AM对应540分钟,5:00 PM对应1020分钟,深夜12:00 AM对应0分钟,数值比较完全符合时间逻辑。
- 显式转换
day_id为数字,避免字符串与数字比较的隐式转换问题。 - 用Moment的
moment(timeStr, 'h:mm A')解析时间字符串,确保转换精度。
修改后,深夜时段的currentMinutes会落在0-539区间,小于开门时间的540分钟,currentMinutes >= openMinutes条件不成立,不会错误匹配已关门的场馆。
内容的提问来源于stack exchange,提问作者almostasnecessary
相关产品推荐
相关产品推荐

