2012-04-07 13 views
21

Quiero crear una instancia de DateTime que mienta 20 minutos y 10 segundos en el futuro. Intenté con Time y DateTime en irb, pero parece que no puedo encontrar una manera que realmente tenga sentido. Solo puedo agregar días a los objetos DateTime y solo agregar segundos a los objetos Time.Manipulación de tiempo en ruby ​​

¿No hay una mejor manera que siempre convertir el tiempo que quiero agregar en segundos?

Respuesta

46

A Time es una cantidad de segundos sin ce una época, mientras que DateTime es un número de días desde una época por lo que agregar 1 a DateTime agrega un día entero. Sin embargo, puede sumar fracciones de un día, por ejemplo

d = DateTime.now 
d + Rational(10, 86400) 

Agregará 10 segundos para d (ya que hay 86.400 segundos en un día).

Si está utilizando rieles, ActiveSupport añade algunos métodos de ayuda y se puede hacer

d + 20.minutes + 10.seconds 

Qué va a hacer lo correcto es d es una DateTime o una Time. Puede usar ActiveSupport por sí mismo, y en estos días puede obtener solo los bits que necesita. Me parece recordar que esto está en activesupport/duration. Creo que hay algunas otras gemas que ofrecen ayuda con el manejo del tiempo también.

+5

Personalmente prefiero escribir '60 * 60 * 24' para que sea un poco más obvio de dónde viene el número mágico, aunque obviamente será un poco más lento en tiempo de ejecución. –

+0

@AndrewMarshall De acuerdo, y a menos que uno esté realizando esta manipulación 'DateTime' millones y millones de veces, dos operaciones de multiplicación más no valen * micro-optimización *. Ni siquiera lo pienses hasta que te topes con un problema de rendimiento.Mejor aún, ¿qué tal si declaramos una constante al comienzo del código? 'SECONDS_PER_DAY = 60 * 60 * 24', y úsalo. Lo mismo podría hacerse para 'MINUTERS_PER_DAY = 60 * 24' y' HOURS_PER_DAY = 24', aunque tal vez el último no sea necesario, pero es bueno ser consistente y simplemente enumerarlos todos. –

2

Bueno, la interfaz es sencilla y directa:

t = Time.now 
t + (20 * 60 + 10) 

Si usted quiere tener algo conveniente, se podría añadir métodos a la clase Time:

class Time 
    def add_minutes(m) 
    self + (60 * m) 
    end 
end 

Pero no creo que esto es más simple:

t = Time.now 
t.add_minutes(20) + 10 
+4

OP quiere DateTime, no Time. – steenslag

2

Suponiendo que ha requerido ActiveSupport o está trabajando en un proyecto de Rails. Una muy simple una forma legible para hacer esto en rubí es:

DateTime + 5.minutes 
Time + 5.minutes 

también trabaja con .seconds, .hours, .days, .weeks, .month, .years

+16

Tenga en cuenta que esto supone que tiene ActiveSupport o Rails. –

+0

gracias por la información - pensé que este es el comportamiento estándar de Ruby – alex

2

Sólo tiene que utilizar las extensiones de tiempo de asistencia activos. Son muy convenientes y menos propensos a errores que tratar de hacer esto a mano. Puede importar sólo el módulo que necesita:

# gem 'activesupport' 
require 'active_support/core_ext/numeric/time.rb' 
DateTime.now + 20.minutes 

NB: Sí, esto va en contra de la línea del partido Stackoverflow de permanecer lejos de las bibliotecas 3 ª parte, pero no se debe evitar el uso de bibliotecas cuando están prácticamente estándar, reduzca su riesgo significativamente y brinde una mejor claridad de código.

Cuestiones relacionadas