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.
Si puedo usar Time
lugar de DateTime
(hay varias formas de traducir uno a otro ):
# Just remove the number of seconds from the Time object
Time.now - (6 * 60 * 60) # 6 hours ago
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