1

如何将ice_cube gem 用于同时具有开始和结束时间的项目(事件)(例如:周一、周三、周五 @ 10pm-11:30pm EST)?

我目前以 UTC 格式将所有时间存储在数据库中。因此,对于上面的示例,该项目如下所示:

#<Item recurring: {:validations=>{:day=>[1, 3, 5]}, :rule_type=>"IceCube::WeeklyRule", :interval=>1, :week_start=>0}, start_time: "2017-11-21 03:00:00", end_time: "2017-12-24 04:30:00"">

如果我想查看该项目是否出现在两次之间的日期,我正在尝试这样做:

item.schedule(item.start_time).occurs_between?(some_start_time, some_end_time)

不幸的是,如果我在(Mon @ 10pm EST) 和( Mon @ 11:30 EST)false传递,这将返回。我相信那是因为宝石只会显示周一、周三、周五与我设置的规则的冲突?some_start_timeTue, 28 Nov 2017 03:00:00 UTC +00:00some_end_timeTue, 28 Nov 2017 04:30:00 UTC +00:00ice_cube

我觉得我错过了关于宝石的一些基本知识。如何正确计算时区?我认为最终目标是,如果我让用户从晚上 10 点到晚上 11:30 选择周一、周三、周五,我需要它将重复存储为周二、周四、周六凌晨 3 点到凌晨 4 点 30 分。

这是我Item在 Rails 中实现课程的方式。

class Item
  serialize :recurring, Hash

  def recurring=(value)
    RecurringSelect.is_valid_rule?(value) ? super(RecurringSelect.dirty_hash_to_rule(value).to_hash) : super(nil)
  end

  def rule
    IceCube::Rule.from_hash(recurring)
  end

  def schedule(start)
    schedule = IceCube::Schedule.new(start)
    schedule.add_recurrence_rule(rule)
    schedule
  end
end

更新

我也在使用recurrence_select gem。这就是让用户轻松选择“每周周一、周三和周五”的原因。我分别让用户为项目选择start_timeend_time。当我保存到数据库时,我正确地将时间从他们的时区转换为 UTC。我不知何故需要知道日子是否也会过去并在保存之前对其进行修改。

4

1 回答 1

1

TL/DR;是的,因为你的规则是 M、W、F,所以当你在星期二通过时,你会得到错误的结果。

更多信息:

从文档中,“计划的发生将在与计划的 start_time 相同的类和时区中返回。” 如果您通过 UTC,它将以 UTC(或您选择的任何时区)返回。

时区很痛苦,但是有几个 Rails 助手可以让你走上正确的轨道(http://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html)。您以 UTC 格式将所有内容保存到数据库的本能是一种很好的本能。诀窍是跟踪日子。本质上,您需要有一种方法为用户提供在他们的时区有意义的显示,然后将其转换为 UTC 中的数据库,并将其适当地传递给您的规则。

看看这个帮助器,它允许您在时区之间进行转换,甚至传入一个日期参数来优化您希望将实际时间附加到哪个日期:https ://github.com/LaunchPadLab/rails_util/blob/master/ lib/rails_util/timezone_helper.rb

不尝试推广,您不必使用该库,但可能值得看看我们提出的逻辑,看看您是否可以将这种想法应用到您的应用程序中。

于 2017-11-28T04:33:40.263 回答