rails parse ruby datetime subtract hour

parse - ruby time



Reste n horas de DateTime en Ruby (11)

El método de avance es bueno si quieres ser más explícito sobre este tipo de comportamiento.

adjusted = time_from_form.advance(:hours => -n)

Tengo un Ruby DateTime que se llena desde un formulario. Además, tengo n horas del formulario también. Me gustaría restar esas n horas del DateTime anterior. (Para obtener un rango de tiempo).

DateTime tiene dos métodos "-" y "<<" para restar el día y el mes, pero no la hora. ( API ). ¿Alguna sugerencia de cómo puedo hacer eso?


Me gusta usar los ayudantes en active_support. Lo hace realmente limpio y fácil de leer.

Vea el ejemplo a continuación:

require ''active_support'' last_accessed = 2.hours.ago last_accessed = 2.weeks.ago last_accessed = 1.days.ago

Puede haber una forma de usar ese tipo de sintaxis para hacer lo que está buscando, si se usa la fecha actual.


No dijiste qué uso necesitas para obtener el valor que obtienes, ¿pero qué hay de solo dividir tus horas entre 24 para que restaras una fracción de un día?

mydatetime = DateTime.parse(formvalue) nhoursbefore = mydatetime - n / 24.0


Podrías hacer esto.

adjusted_datetime = (datetime_from_form.to_time - n.hours).to_datetime


Puedes restar menos de un día entero:

two_hours_ago = DateTime.now - (2/24.0)

Esto funciona por minutos y cualquier otra cosa también:

hours = 10 minutes = 5 seconds = 64 hours = DateTime.now - (hours/24.0) #<DateTime: 2015-03-11T07:27:17+02:00 ((2457093j,19637s,608393383n),+7200s,2299161j)> minutes = DateTime.now - (minutes/1440.0) #<DateTime: 2015-03-11T17:22:17+02:00 ((2457093j,55337s,614303598n),+7200s,2299161j)> seconds = DateTime.now - (seconds/86400.0) #<DateTime: 2015-03-11T17:26:14+02:00 ((2457093j,55574s,785701811n),+7200s,2299161j)>

Si las imprecisiones aritméticas de punto flotante son un problema, puede usar Rational o alguna otra utilidad aritmética segura.


Puedes usar esto:

Time.now.ago(n*60*60)

Por ejemplo, Time.now.ago(7200) dará la fecha y hora que era antes de 2 horas a partir de ahora.



Solo necesitas quitar fracciones de un día.

two_hours_ago = DateTime.now - (2.0/24)

  • 1.0 = un día
  • 1.0 / 24 = 1 hora
  • 1.0 / (24 * 60) = 1 minuto
  • 1.0 / (24 * 60 * 60) = 1 segundo

DateTime no puede hacer esto, pero Time puede:

t = Time.now t = t-hours*60

Tenga en cuenta que Time también almacena información de fecha, todo es un poco extraño.

Si tienes que trabajar con DateTime

DateTime.commercial(date.year,date.month,date.day,date.hour-x,date.minute,date.second)

podría funcionar, pero es feo El documento dice que DateTime es inmutable, por lo que ni siquiera estoy seguro de - y <<


n/24.0 truco n/24.0 no funcionará correctamente ya que los flotadores finalmente se redondean:

>> DateTime.parse(''2009-06-04 02:00:00'').step(DateTime.parse(''2009-06-04 05:00:00''),1.0/24){|d| puts d} 2009-06-04T02:00:00+00:00 2009-06-04T03:00:00+00:00 2009-06-04T03:59:59+00:00 2009-06-04T04:59:59+00:00

Sin embargo, puedes usar la clase Rational:

>> DateTime.parse(''2009-06-04 02:00:00'').step(DateTime.parse(''2009-06-04 05:00:00''),Rational(1,24)){|d| puts d} 2009-06-04T02:00:00+00:00 2009-06-04T03:00:00+00:00 2009-06-04T04:00:00+00:00 2009-06-04T05:00:00+00:00


EDITAR : Eche un vistazo a esta pregunta antes de decidir usar el enfoque que he esbozado aquí. Parece que no es una buena práctica modificar el comportamiento de una clase base en Ruby (que puedo entender). Por lo tanto, tome esta respuesta con un grano de sal ...

La respuesta de MattW fue lo primero que pensé, pero tampoco me gustó demasiado.

Supongo que podrías hacerlo menos feo parcheando DateTime y Fixnum para hacer lo que quieras:

require ''date'' # A placeholder class for holding a set number of hours. # Used so we can know when to change the behavior # of DateTime#-() by recognizing when hours are explicitly passed in. class Hours attr_reader :value def initialize(value) @value = value end end # Patch the #-() method to handle subtracting hours # in addition to what it normally does class DateTime alias old_subtract - def -(x) case x when Hours; return DateTime.new(year, month, day, hour-x.value, min, sec) else; return self.old_subtract(x) end end end # Add an #hours attribute to Fixnum that returns an Hours object. # This is for syntactic sugar, allowing you to write "someDate - 4.hours" for example class Fixnum def hours Hours.new(self) end end

Entonces puedes escribir tu código así:

some_date = some_date - n.hours

donde n es la cantidad de horas que quiere some_date de some_date