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

如何在Rails中移除日期数组中指定时段外的元素?

问题:筛选Datetime数组中的指定时间段元素

需求说明

通过以下Ruby代码生成包含连续Datetime元素的数组(最多覆盖62天,每30分钟一个元素):

start_date = (Date.today + 10.hours + 30.minutes).to_datetime       
end_date = (Date.today + 1.day + 18.hours).to_datetime
period = 0.5/24 
array = start_date.step(end_date, period).to_a

需要移除数组中所有处于每天00:00至10:29,以及18:00至当天结束的Datetime元素,最终只保留每天10:30到18:00之间的元素。

原代码问题分析

你尝试的代码返回nil,核心问题有两个:

  1. 字符串比较时间逻辑错误:用strftime('%k:%M:%S')转换后的字符串做between?判断,会因字符串字典序逻辑导致时间判断失效;且w_start_time、w_end_time基于start_date偏移计算,没有针对每个元素的当天时间做判断,完全偏离需求。
  2. reject!的返回特性:reject!是破坏性方法,会直接修改原数组;当数组中没有符合条件的元素被移除时,它会返回nil而非修改后的数组。建议用非破坏性方法select或reject生成新数组。

解决方案

直接针对每个Datetime元素的时分数值做判断,筛选符合时间范围的元素,以下是两种简洁可靠的实现:

方法1:直接判断时分

filtered_array = array.select do |dt|
  hour = dt.hour
  minute = dt.min
  # 筛选10:30及以后、18:00及以前的时间
  (hour > 10 || (hour == 10 && minute >= 30)) && (hour < 18 || (hour == 18 && minute == 0))
end

方法2:转换为当天总分钟数判断

将时间转换为当天的总分钟数,用区间判断更直观:

filtered_array = array.select do |dt|
  daily_total_minutes = dt.hour * 60 + dt.min
  # 10:30对应630分钟,18:00对应1080分钟
  (630..1080).include?(daily_total_minutes)
end

两种方法都能准确筛选目标时间段元素,且不受数组覆盖天数限制,逻辑清晰可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 03:23:29