How to generate a random date in Ruby?

24,854

Solution 1

Here's a slight expansion on Chris' answer, with optional from and to parameters:

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 

Solution 2

Generate a random time between epoch, the beginning of 1970, and now:

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

Solution 3

Keeping simple..

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

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

PS. Increasing/Decreasing the '10000' parameter, changes the range of dates available.

Solution 4

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

my favorite method

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

then use like

random_date = random_date_in_year(2000..2020)

Solution 5

The prettiest solution to me is:

rand(1.year.ago..50.weeks.from_now).to_date
Share:
24,854
Misha Moroshko
Author by

Misha Moroshko

I build products that make humans happier. Previously Front End engineer at Facebook. Now, reimagining live experiences at https://muso.live

Updated on July 09, 2022

Comments

  • Misha Moroshko
    Misha Moroshko almost 2 years

    I have a model in my Rails 3 application which has a date field:

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

    I would like to prepopulate my database with random date values.

    What is the easiest way to generate a random date ?

  • Иван Бишевац
    Иван Бишевац over 11 years
    It works. Just wondering could it be simplified with Time.at(rand * Time.now.to_f)?
  • vvohra87
    vvohra87 over 11 years
    I keep wondering when this will become part of ruby core! Like rand(date1..date2)!
  • likethesky
    likethesky almost 11 years
    Btw, there's a bug in JRuby right now, so I had to use an extra .to_time before sending to Time.at--in order to get it to work in JRuby 1.7.4--like this: Time.at((from + rand * (to.to_f - from.to_f)).to_time)
  • Fran Martinez
    Fran Martinez about 9 years
    This is returning a Time, not a Date. to return a date, just add "to_date" at the end. (Comparisons between Date and Time will send you an error in rails)
  • Cyril Duchon-Doris
    Cyril Duchon-Doris about 7 years
    @VarunVohra Shit this is actually already core for me on Rails 5 / Ruby 2.3 (not sure from which it is coming from)
  • vvohra87
    vvohra87 about 7 years
    @CyrilDuchon-Doris This was around rails 3.x and ruby 1.9.x if I recall correctly.