JavaScript中跨午夜时间段的时间比较问题(基于Luxon库)
解决Luxon跨午夜时间区间判断问题
问题原因
Luxon的Interval.fromDateTimes会将传入的DateTime视为完整的日期时间对象——当你只传入时间字符串时,它会默认使用当前日期。比如你代码里的from是「今天20:00」,to是「今天10:00」,此时from的时间戳远大于to,Luxon会判定这个区间是反向无效区间,因此contains方法无法正确识别「01:00」属于该跨午夜区间。
而你实际需要的逻辑是:判断时间是否落在「当天20:00到次日10:00」或「当天00:00到10:00」这类区间内。
解决方案
方案1:直接比较时间的分钟数(推荐,简单高效)
把时间转换为一天内的总分钟数,通过判断区间是否跨午夜,分别处理逻辑:
const { DateTime } = require('luxon'); // 将DateTime转换为一天内的总分钟数(忽略日期) const getTotalMinutes = (dt) => dt.hour * 60 + dt.minute; const from = DateTime.fromISO('20:00'); const to = DateTime.fromISO('10:00'); const value = DateTime.fromISO('01:00'); const fromMins = getTotalMinutes(from); const toMins = getTotalMinutes(to); const valueMins = getTotalMinutes(value); let isInInterval; if (fromMins > toMins) { // 跨午夜区间:时间 >= 起始时间 或 <= 结束时间 isInInterval = valueMins >= fromMins || valueMins <= toMins; } else { // 常规区间:时间在起始和结束之间 isInInterval = valueMins >= fromMins && valueMins <= toMins; } console.log(isInInterval); // 输出 true(符合预期)
方案2:手动构建跨天的Interval对象
如果需要保留Luxon的Interval对象(用于其他Interval方法),可以手动将结束时间的日期加1天,再判断时间是否在区间内:
const { DateTime, Interval } = require('luxon'); const from = DateTime.fromISO('20:00'); const to = DateTime.fromISO('10:00'); const value = DateTime.fromISO('01:00'); // 处理跨午夜:如果起始时间晚于结束时间,将结束时间加1天 const adjustedTo = from > to ? to.plus({ days: 1 }) : to; const interval = Interval.fromDateTimes(from, adjustedTo); // 把待判断的时间转换为与起始时间同日期,同时检查次日的同一时间是否在区间内 const valueSameDay = value.set({ year: from.year, month: from.month, day: from.day }); const valueNextDay = valueSameDay.plus({ days: 1 }); const isInInterval = interval.contains(valueSameDay) || interval.contains(valueNextDay); console.log(isInInterval); // 输出 true
内容的提问来源于stack exchange,提问作者Lemour
相关产品推荐
相关产品推荐

