在Rails中创建随机DateTime的最佳方法

时间:2010-03-09 16:30:23

标签: ruby-on-rails

在Ruby / Rails中生成随机DateTime的最佳方法是什么?试图创建一个漂亮的seeds.rb文件。要像这样使用它:

 Foo.create(name: Faker::Lorem.words, description: Faker::Lorem.sentence, start_date: Random.date)

12 个答案:

答案 0 :(得分:121)

以下是过去10年中如何创建日期:

rand(10.years).ago

您还可以在将来获得日期:

rand(10.years).from_now

更新 - Rails 4.1 +

Rails 4.1已弃用Numeric =>的隐式转换您拨打上述代码所依赖的.ago时的秒数。有关详细信息,请参阅Rails PR #12389。要避免Rails 4.1中的弃用警告,您需要显式转换为秒,如下所示:

rand(10.years).seconds.ago

答案 1 :(得分:34)

以下是一组用于生成范围内的随机整数,金额,时间/日期时间的方法。

def rand_int(from, to)
  rand_in_range(from, to).to_i
end

def rand_price(from, to)
  rand_in_range(from, to).round(2)
end

def rand_time(from, to=Time.now)
  Time.at(rand_in_range(from.to_f, to.to_f))
end

def rand_in_range(from, to)
  rand * (to - from) + from
end

现在您可以拨打以下电话。

rand_int(60, 75)
# => 61

rand_price(10, 100)
# => 43.84

rand_time(2.days.ago)
# => Mon Mar 08 21:11:56 -0800 2010

答案 2 :(得分:17)

我更喜欢使用(1..500).to_a.rand.days.ago

答案 3 :(得分:11)

您正在使用Faker;为什么不使用Faker::Date提供的方法之一?

# Random date between dates
Faker::Date.between(2.days.ago, Date.today) #=> "Wed, 24 Sep 2014"

# Random date between dates except for certain date
Faker::Date.between_except(1.year.ago, 1.year.from_now, Date.today) #=> "Wed, 24 Sep 2014"

# Random date in the future (up to maximum of N days)
Faker::Date.forward(23) # => "Fri, 03 Oct 2014"

# Random date in the past (up to maximum of N days)
Faker::Date.backward(14) #=> "Fri, 19 Sep 2014"

# Random birthday date (maximum age between 18 and 65)
Faker::Date.birthday(18, 65) #=> "Mar, 28 Mar 1986"

目前的Faker版本:1.9.1

答案 4 :(得分:2)

以下是如何在本月创建日期:

day = 1.times.map{ 0+Random.rand(30) }.join.to_i  
rand(day.days).ago

答案 5 :(得分:2)

这就是我使用的:

# get random DateTime in last 3 weeks
DateTime.now - (rand * 21)

答案 6 :(得分:1)

其他方式:

(10..20).to_a.sample.years.ago

答案 7 :(得分:1)

使用DateTime's advance

的另一种方法
def rand_date
  # return a random date within 100 days of today in both past and future directions.
  n = rand(-100..100)
  Date.today.advance(days: n)
end

答案 8 :(得分:0)

我自己没有尝试过,但你可以使用自纪元以来的秒数在两个日期之间创建一个随机整数。例如,获取上周的随机日期。

end = Time.now
start = (end - 1.week).to_i
random_date = Time.at(rand(end.to_i - start)) + start

当然你最终会得到一个Time对象而不是DateTime,但我相信你可以从这里隐身。

答案 9 :(得分:0)

正如我在另一个问题中已经提到的,我认为以下代码片段对于参数的数据类型和要返回的值更为明确。 Stackoverflow: How to generate a random date in Ruby?

无论如何,这使用了rand()方法的内部逻辑什么是随机日期或跨度内的随机时间。也许某人有一种更有效的方法来设置方法 random_date 的默认参数(Time.now.to_date),因此它不需要这种类型转换。< / p>

def random_time from = Time.at(0.0), to = Time.now
  rand(from..to)
end

# works quite similar to date :)
def random_date from = Date.new(1970), to = Time.now.to_date
  rand(from..to)
end

编辑:此代码在ruby v1.9.3

之前不起作用

答案 10 :(得分:0)

您可以将时间范围传递到rand

rand(10.weeks.ago..1.day.ago)

输出示例:

=> Fri, 10 Jan 2020 10:28:52 WIB +07:00

答案 11 :(得分:-1)

我的'ish'宝石提供了一种处理这个问题的好方法:

# plus/minus 5 min of input date
Time.now.ish
# override that time range like this
Time.now.ish(:offset => 1.year)

https://github.com/spilliton/ish