Каков наилучший способ генерации случайной даты в Ruby/Rails? Попытка создать хороший файл seeds.rb. Чтобы использовать его так:
Foo.create(name: Faker::Lorem.words, description: Faker::Lorem.sentence, start_date: Random.date)
Каков наилучший способ генерации случайной даты в Ruby/Rails? Попытка создать хороший файл seeds.rb. Чтобы использовать его так:
Foo.create(name: Faker::Lorem.words, description: Faker::Lorem.sentence, start_date: Random.date)
Здесь приведены методы для генерации случайного целого числа, количества, времени/даты и времени в пределах диапазона.
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
Вот как создать дату за последние 10 лет:
rand(10.years).ago
Вы также можете получить дату в будущем:
rand(10.years).from_now
Rails 4.1 устарел на неявное преобразование из Numeric = > seconds, когда вы вызываете .ago
, от которого зависит вышеуказанный код. Подробнее см. Rails PR # 12389. Чтобы избежать предупреждения об отказе в Rails 4.1, вам нужно сделать явное преобразование в секундах, например:
rand(10.years).seconds.ago
Я предпочитаю использовать (1..500).to_a.rand.days.ago
Вы используете Faker: почему бы не использовать Faker::Time.between()
?
(https://github.com/stympy/faker#fakertime)
Вот как создать дату в этом месяце:
day = 1.times.map{ 0+Random.rand(30) }.join.to_i
rand(day.days).ago
другой способ:
(10..20).to_a.sample.years.ago
Другой подход, использующий DateTime 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
Это то, что я использую:
# get random DateTime in last 3 weeks
DateTime.now - (rand * 21)
Я не пробовал это сам, но вы могли бы создать случайное целое число между двумя датами, используя количество секунд с эпохи. Например, чтобы получить случайную дату на прошлой неделе.
end = Time.now
start = (end - 1.week).to_i
random_date = Time.at(rand(end.to_i - start)) + start
Конечно, вы получаете объект Time вместо DateTime, но я уверен, что вы можете скрыться отсюда.
Как я уже упоминал в другом вопросе, я думаю, что следующий фрагмент кода более сложен в отношении типов данных параметров и возвращаемого значения. fooobar.com/questions/167459/...
В любом случае это использует внутреннюю логику rand(), что является случайной датой или случайным временем в пределах диапазона. Возможно, у кого-то есть более эффективный способ установить параметр по умолчанию на (Time.now.to_date) метода random_date, поэтому ему не нужно это приведение типов.
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
My 'ish' gem обеспечивает хороший способ справиться с этим:
# plus/minus 5 min of input date
Time.now.ish
# override that time range like this
Time.now.ish(:offset => 1.year)