/ / Obtenga objetos de tiempo aleatorios entre ciertas horas en Rails: ruby-on-rails, ruby, datetime

Obtenga objetos de tiempo aleatorio entre ciertas horas en Rails: ruby-on-rails, ruby, datetime

Quisiera un método que:

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

Aquí hay dos preguntas: cómo implementar ***? y como implementar x.pm.of_today?

Respuestas

7 para la respuesta № 1

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)

0 para la respuesta № 2

Este es un primer intento:

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

Aunque funciona como:

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

Creo que es suficiente, pero estaré abierto a mejores soluciones.


0 para la respuesta № 3

Para obtener el intervalo de tiempo aleatorio, deberá calcular la distancia entre los dos tiempos. Obtenga un valor aleatorio con ese intervalo de distancia. Y finalmente agréguelo a su tiempo.

Algo como: (pero no lo voy a probar)

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

En cuanto a crear un DSL por tiempo.Podrías ver cómo lo hace Rails. Pero para conseguir algo como lo que estás deseando. Simplemente cree una clase que represente las horas del día. Cree una instancia con la llamada am o pm en un Fixnum. Luego escribe los métodos para of_today (y cualquier otro que desee).

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

Debe agregar algún manejo de errores durante más de 24 horas.


0 para la respuesta № 4

Este código respeta los minutos y las horas como entrada.

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")

Otra forma corta de hacer lo mismo:

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")