¿Rails ActiveSupport Time Parsing?

votos
30

El módulo ActiveSupport de Rails amplía la clase de tiempo ruby ​​incorporada con varios métodos.

En particular, existe el to_formatted_smétodo, que le permite escribir Time.now.to_formatted_s(:db)para obtener una cadena en formato de base de datos, en lugar de tener que escribir strftimecadenas de formato feo en todas partes.

Mi pregunta es, ¿hay alguna manera de ir hacia atrás?

Algo así como Time.parse_formatted_s(:db)analizar una cadena en formato de Base de Datos, devolver un nuevo objeto de Tiempo. Esto parece algo que los rieles deberían proporcionar, pero si lo es, no puedo encontrarlo.

¿Acaso no puedo encontrarlo o tengo que escribirlo yo mismo?

Gracias

Publicado el 10/12/2008 a las 00:52
fuente por usuario
En otros idiomas...                            


5 respuestas

votos
55

Parece que ActiveSupport proporciona los métodos de análisis que está buscando (y yo también estaba buscando), ¡después de todo! - al menos si la cadena que está tratando de analizar es una fecha estándar, con formato ISO-8601 ( :dbformato).

Si la fecha que intentas analizar ya está en tu zona horaria local, ¡es realmente fácil!

 > Time.zone.parse('2009-09-24 08:28:43')
=> Thu, 24 Sep 2009 08:28:43 PDT -07:00

 > Time.zone.parse('2009-09-24 08:28:43').class
=> ActiveSupport::TimeWithZone

y ese tiempo de reconocimiento de zona horaria puede convertirse fácilmente a UTC

 > Time.zone.parse('2009-09-24 08:28:43').utc
=> 2009-09-24 15:28:43 UTC

o a otras zonas horarias:

 > ActiveSupport::TimeZone.us_zones.map(&:name)
=> ["Hawaii", "Alaska", "Pacific Time (US & Canada)", "Arizona", "Mountain Time (US & Canada)", "Central Time (US & Canada)", "Eastern Time (US & Canada)", "Indiana (East)"]

 > Time.zone.parse('2009-09-24 08:28:43').utc.in_time_zone('Eastern Time (US & Canada)')
=> Thu, 24 Sep 2009 11:28:43 EDT -04:00

Si la cadena de fecha que está tratando de analizar está en UTC, por otro lado, no parece que haya ningún método para analizarlo directamente en TimeWithZone, pero pude evitarlo usando DataTime.strptime ...

Si la fecha que intenta analizar está en UTC y desea que permanezca como UTC, puede usar:

 > DateTime.strptime('2009-09-24 08:28:43', '%Y-%m-%d %H:%M:%S').to_time
=> 2009-09-24 08:28:43 UTC

Si la fecha que intenta analizar está en UTC y desea convertirla a su zona horaria predeterminada, puede usar:

 > DateTime.strptime('2009-09-24 08:28:43', '%Y-%m-%d %H:%M:%S').to_time.in_time_zone
=> Thu, 24 Sep 2009 01:28:43 PDT -07:00

Parece que incluso puede analizar otros formatos, como el extraño formato que produce Time # to_s:

irb -> Time.zone.parse('Wed, 23 Sep 2009 02:18:08').to_s(:db)
    => "2009-09-23 09:18:08"

irb -> Time.zone.parse('Wed, 23 Sep 2009 02:18:08 EDT').to_s(:db)
    => "2009-09-23 06:18:08"

Estoy bastante impresionado.

Aquí hay algunos ejemplos más de [ http://api.rubyonrails.org/classes/ActiveSupport/TimeWithZone.html][1] :

  Time.zone = 'Eastern Time (US & Canada)'        # => 'Eastern Time (US & Canada)'
  Time.zone.local(2007, 2, 10, 15, 30, 45)        # => Sat, 10 Feb 2007 15:30:45 EST -05:00
  Time.zone.parse('2007-02-10 15:30:45')          # => Sat, 10 Feb 2007 15:30:45 EST -05:00
  Time.zone.at(1170361845)                        # => Sat, 10 Feb 2007 15:30:45 EST -05:00
  Time.zone.now                                   # => Sun, 18 May 2008 13:07:55 EDT -04:00
  Time.utc(2007, 2, 10, 20, 30, 45).in_time_zone  # => Sat, 10 Feb 2007 15:30:45 EST -05:00

Más enlaces de documentación para referencia:

Respondida el 24/09/2009 a las 22:24
fuente por usuario

votos
5
ActiveSupport::TimeZone.new('UTC').parse('2009-09-23 09:18:08')
=> Wed, 23 Sep 2009 09:18:08 UTC +00:00
Respondida el 05/08/2010 a las 17:17
fuente por usuario

votos
3

Carriles 5, finalmente, proporciona strptime!

value = '1999-12-31 14:00:00'
format = '%Y-%m-%d %H:%M:%S'
Time.zone.strptime(value, format)
# => Fri, 31 Dec 1999 14:00:00 HST -10:00

ActiveSupport::TimeZone.all.sample.strptime(value, format)
# => Fri, 31 Dec 1999 14:00:00 GST +04:00
Respondida el 07/02/2016 a las 03:36
fuente por usuario

votos
2

Me acabo de encontrar con esto también y ninguna de las respuestas anteriores fueron satisfactorios para mí. Lo ideal sería que se podría utilizar ActiveSupport::TimeZonecomo Timey llamar .strptimeen él con cualquier formato arbitrario y recuperar el correcto TimeZoneobjeto. ActiveSupport::TimeZone.strptimeno existe así que creé este monkeypatch:

 class ActiveSupport::TimeZone
    def strptime(str, fmt, now = self.now)
      date_parts = Date._strptime(str, fmt)
      return if date_parts.blank?
      time = Time.strptime(str, fmt, now) rescue DateTime.strptime(str, fmt, now)
      if date_parts[:offset].nil?
        ActiveSupport::TimeWithZone.new(nil, self, time)
      else
        time.in_time_zone(self)
      end
    end
  end
Respondida el 17/05/2012 a las 23:37
fuente por usuario

votos
1
>> "2009-09-24".to_date
=> Thu, 24 Sep 2009
>> "9/24/2009".to_date
=> Thu, 24 Sep 2009

Funciona muy bien a menos que su fecha esté en algún formato raro.

Respondida el 25/09/2009 a las 02:40
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more