38

Don't overlook the 'date AND TIME' part though.

potashin
  • 44,205
  • 11
  • 83
  • 107
Hermine D.
  • 1,119
  • 3
  • 14
  • 19

9 Answers9

62
Time.at((date2.to_f - date1.to_f)*rand + date1.to_f)

You'll get a time object that is between two given datetimes.

Evgeny Shadchnev
  • 7,320
  • 4
  • 27
  • 30
  • 10
    This is a great solution however a note may be in order; you will need to convert your date to a time in order to call `to_f` on it. `Date` does not have a `to_f`. i.e. `Date.today.to_time` – rmontgomery429 Nov 03 '11 at 15:11
  • I need to find a way to give you another +1 - 2nd time this week I've referred to this answer! – vvohra87 Nov 27 '11 at 06:09
  • 2
    For me, now at least, in 1.9.3, I can do `date1 + (date2 - date1) * rand`, and it comes out as a time. – nroose Jul 19 '13 at 01:42
  • 4
    Or even simpler: `rand((DateTime.now - 3.months)..DateTime.now)` – XtraSimplicity May 10 '19 at 09:23
44

You should be able to generate random date/times within a certain range.

now = Time.now
a_day_ago = now - 60 * 60 * 24

random_time = rand(a_day_ago..now)

# with activesupport required
up_to_a_year_ago = rand(1.year.ago..Time.now)

Your inputs need to be the Time class, or converted into one though.

You could do also do a range of time in epoch time and then use Time#at.

now = Time.now.to_i
minute_ago = (Time.now - 60).to_i
Time.at(rand(minute_ago..now))
Jack Chu
  • 6,791
  • 4
  • 38
  • 44
  • 2
    In my opinion, this solution is much nicer than the currently accepted one by Evgeny. – severin Aug 17 '12 at 08:28
  • 1
    One small remark, though: `1.year.ago` only works when you have *activesupport* loaded... – severin Aug 17 '12 at 08:29
  • Good point @severin. I included code for support with and without activesupport loaded. Also added an example for epoch time ranges. – Jack Chu Aug 17 '12 at 17:09
12

Use the rand() method.

require 'time'
t1 = Time.parse("2015-11-16 14:40:34")
t2 = Time.parse("2015-11-20 16:20:23")
puts rand(t1..t2)
user3335966
  • 2,673
  • 4
  • 30
  • 33
SharnieIvery
  • 141
  • 2
  • 6
5

Use time.to_i() (see class Time) to convert your dates to integer, randomize between those two values, then reconvert to time and date with Time.at().

Federico klez Culloca
  • 26,308
  • 17
  • 56
  • 95
2

I don't know about ruby but why don't you just generate an integer and use it together with a timestamp? Then simply convert the timestamp to your desired format.

Max Leske
  • 5,007
  • 6
  • 42
  • 54
1

If you know the midpoint and the offset range on either side of the midpoint you can use my ish gem: https://github.com/spilliton/ish

mid_date.ish(:offset => 60.days)
spilliton
  • 3,811
  • 5
  • 35
  • 35
1
Time.at(rand(Time.parse('some date').to_i..Time.now.to_i))
alebian
  • 786
  • 5
  • 17
1

Simplest way

rand(DateTime.now..3.days.from_now.to_datetime)

0

Calculate the difference in for example minutes between the two dates, generate a random number between 0 and that number, and add that number of minutes to the first date.

Maarten Ureel
  • 393
  • 4
  • 18