Skip to content

Instantly share code, notes, and snippets.

@ekampp
Created August 28, 2012 07:52
Show Gist options
  • Save ekampp/3495978 to your computer and use it in GitHub Desktop.
Save ekampp/3495978 to your computer and use it in GitHub Desktop.
Random time extention
class Date
# Samples a random time
#
# Parameters
# This takes up to three parameters, that is a range of `years`, `months` and
# `days`. Each defining the boundries of the sample date.
#
# Examples
# `Time.random({ years: 1..2 })` will produce a date between one and two
# ears into the future.
#
# `Time.random({ years: -5..5 })` will produce a date after five years ago,
# but before five ears from now.
#
# `Time.random({ years: 1..1 })` will produce a date within the next year
#
# `Time.random({ years: 1..1, months: 3..5 })` will produce a date within
# this year, and between march and may
#
# `Time.random({ years: 1..1, months: 3..5, days: 20..25 })` will produce a
# date between the 20th and 25th between march and may of this year.
#
def self.random(options = {})
years = options[:years] || (-5..5)
months = options[:months] || (1..12)
year = years.to_a.collect{ |y| y >= 0 ? y.years.from_now.year : y.abs.years.ago.year }.sample
month = months.to_a.sample
max_days = Date.civil(year, month, -1).day
days = options[:days] || (1..max_days)
days = (days.min..max_days) if days.max > max_days
day = days.to_a.sample
Date.new(year, month, day)
end
end
@dipth
Copy link

dipth commented Aug 28, 2012

But now it's possible to specify an invalid date again.

Try this:

max_days = Date.civil(year, month, -1).day
days = options[:days] || (1..max_days)
days = (days.min..max_days) if days.max > max_days

@ekampp
Copy link
Author

ekampp commented Aug 28, 2012

Good point :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment