sites
sites

Reputation: 21795

Get random time objects between certain hours in Rails

I would want a method that:

def time_between(from, to)
  ***
end

time_between 10.am.of_today, 3.pm.of_today # => 1pm Time object
time_between 10.am.of_today, 3.pm.of_today # => 3pm Time object
time_between 10.am.of_today, 3.pm.of_today # => 10:30am Time object
# I mean random

There are two questions here: how to implement ***? and how to implement x.pm.of_today?

Upvotes: 3

Views: 2622

Answers (4)

phlegx
phlegx

Reputation: 2742

This code respects minutes and hours as input.

require 'rubygems'
require 'active_support/all'

def random_time(from, to)
  from_arr = from.split(':')
  to_arr   = to.split(':')
  now      = Time.now
  rand(Time.new(now.year, now.month, now.day, from_arr[0], rom_arr[1])..Time.new(now.year, now.month, now.day, to_arr[0], to_arr[1]))
end

puts random_time('09:15', '18:45')

Another short way to do the same:

require 'rubygems'
require 'active_support/all'

def random_time(from, to)
  now      = Time.now
  rand(Time.parse(now.strftime("%Y-%m-%dT#{from}:00%z"))..Time.parse(now.strftime("%Y-%m-%dT#{to}:00%z")))
end

puts random_time('09:15', '18:45')

Upvotes: -1

natedavisolds
natedavisolds

Reputation: 4295

To get the random time slot you will need to calculate the distance between the two times. Get a random value with that distance span. And finally add it to your from time.

Something like: (but I am not going to test it)

def time_between(from, to)
  if from > to
    time_between(to, from)
  else
    from + rand(to - from)
  end
end

As for creating a DSL for time. You could look at how Rails does it. But to get something like what you are wanting. Just create a class that represents the hours in the day. Instantiate it with the am or pm call on a Fixnum. Then write the methods for of_today (and any others that you would want).

class Fixnum
  def am
    TimeWriter.new(self)
  end

  def pm
    TimeWriter.new(self + 12)
  end
end

class TimeWriter
  MINUTES_IN_HOUR = 60
  SECONDS_IN_MINUTE = 60
  SECONDS_IN_HOUR = MINUTES_IN_HOUR * SECONDS_IN_MINUTE

  def initialize hours
    @hours = hours
  end

  def of_today
    start_of_today + (hours * SECONDS_IN_HOUR)
  end

  private

  attr_reader :hours

  def start_of_today
    now = Time.now
    Time.new(now.year, now.month, now.day, 0, 0)
  end
end

You should add some error handling for hours more than 24.

Upvotes: -1

sites
sites

Reputation: 21795

This is a first try:

def time_between(from, to)
  today = Date.today.beginning_of_day
  (today + from.hours)..(today + to.hours).to_a.sample
end

Although it works like:

time_between(10, 15) # => a random time between 10 am and 3 pm

I think is enough, but I'll be open for better solutions.

Upvotes: 0

uokesita
uokesita

Reputation: 301

ruby 1.9.3

require 'rubygems'
require 'active_support/all'

def random_hour(from, to)
  (Date.today + rand(from..to).hour + rand(0..60).minutes).to_datetime
end

puts random_hour(10, 15)

Upvotes: 8

Related Questions