如何在Ruby中生成随机日期?

47

我在我的Rails 3应用程序中有一个模型,其中包含一个日期字段:

class CreateJobs < ActiveRecord::Migration
  def self.up
    create_table :jobs do |t|
      t.date "job_date", :null => false
      ...
      t.timestamps
    end
  end
  ...
end

我想要用随机的日期值预填充我的数据库。

生成随机日期的最简单方法是什么?


你不能直接使用 Time.now 吗?或者你真的需要使用随机日期吗? - corroded
2
我真的想要随机值 :) - Misha Moroshko
12个回答

68

以下是Chris回答的稍微扩展,带有可选的fromto参数:

def time_rand from = 0.0, to = Time.now
  Time.at(from + rand * (to.to_f - from.to_f))
end

> time_rand
 => 1977-11-02 04:42:02 0100 
> time_rand Time.local(2010, 1, 1)
 => 2010-07-17 00:22:42 0200 
> time_rand Time.local(2010, 1, 1), Time.local(2010, 7, 1)
 => 2010-06-28 06:44:27 0200 

3
可以。使用 Time.at(rand * Time.now.to_f) 可以使代码更简洁。 - Иван Бишевац
2
我一直在想,这个功能什么时候会成为 Ruby 核心的一部分!就像 rand(date1..date2) 一样! - vvohra87
顺便提一句,JRuby现在有一个bug,所以我不得不在发送给Time.at之前使用额外的.to_time,为了让它能够在JRuby 1.7.4中工作,像这样:Time.at((from + rand * (to.to_f - from.to_f)).to_time) - likethesky
这将返回一个时间,而不是日期。要返回日期,只需在结尾处添加 "to_date" 即可。(在Rails中比较日期和时间会导致错误) - Fran Martinez
@VarunVohra 这对我来说已经是Rails 5 / Ruby 2.3的核心了(不确定它来自哪里) - Cyril Duchon-Doris
@CyrilDuchon-Doris 如果我没记错的话,这是关于Rails 3.x和Ruby 1.9.x的。 - vvohra87

46

生成从1970年开始到现在之间的随机时间:

Time.at(rand * Time.now.to_i)

23

简单来说...

Date.today-rand(10000) #for previous dates

Date.today+rand(10000) #for future dates

顺便提一下,增加/减少 "10000" 参数会改变可用日期的范围。


17
rand(Date.civil(1990, 1, 1)..Date.civil(2050, 12, 31))

我最喜欢的方法

def random_date_in_year(year)
  return rand(Date.civil(year.min, 1, 1)..Date.civil(year.max, 12, 31)) if year.kind_of?(Range)
  rand(Date.civil(year, 1, 1)..Date.civil(year, 12, 31))
end

然后像使用这样:

random_date = random_date_in_year(2000..2020)

7

我认为最漂亮的解决方案是:

rand(1.year.ago..50.weeks.from_now).to_date

7

对于最近版本的Ruby/Rails,您可以在Time范围内使用rand❤️ !!

min_date = Time.now - 8.years
max_date = Time.now - 1.year
rand(min_date..max_date)
# => "2009-12-21T15:15:17.162+01:00" (Time)

随意添加to_dateto_datetime等方法,以将其转换为您喜欢的类

已在Rails 5.0.3和Ruby 2.3.3上测试,但显然可用于Ruby 1.9+和Rails 3+


4
以下代码返回 Ruby(不包括 Rails)中过去 3 周内的随机日期时间: DateTime.now - (rand * 21)

3

这里是Mladen代码片段的更改版本(在我看来更好)。幸运的是,Ruby的rand()函数也可以处理时间对象。关于日期对象在包含Rails时被定义,rand()方法被覆盖以便也可以处理日期对象。例如:

# works even with basic ruby
def random_time from = Time.at(0.0), to = Time.now
  rand(from..to)
end

# works only with rails. syntax is quite similar to time method above :)
def random_date from = Date.new(1970), to = Time.now.to_date
  rand(from..to)
end

编辑:此代码在 ruby v1.9.3 之前无法运行


2
这是一个生成最近30天内随机日期的一行代码(例如):
Time.now - (0..30).to_a.sample.days - (0..24).to_a.sample.hours

对于我的lorem ipsum来说非常有效。显然,分钟和秒钟将被固定。


1

由于您正在使用Rails,您可以安装faker gem并利用Faker::Date模块。

例如,以下代码将生成2018年内的随机日期:

Faker::Date.between(Date.parse('01/01/2018'), Date.parse('31/12/2018'))


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接