Convertir à / de DateTime et Heure en Ruby

Comment convertissez-vous entre un object DateTime et un object Time dans Ruby?

Related of "Convertir à / de DateTime et Heure en Ruby"

Vous aurez besoin de deux conversions légèrement différentes.

Pour convertir de Time à DateTime vous pouvez modifier la classe de temps comme suit:

 require 'date' class Time def to_datetime # Convert seconds + microseconds into a fractional number of seconds seconds = sec + Rational(usec, 10**6) # Convert a UTC offset measured in minutes to one measured in a # fraction of a day. offset = Rational(utc_offset, 60 * 60 * 24) DateTime.new(year, month, day, hour, min, seconds, offset) end end 

Des ajustements similaires à Date vous permettront de convertir DateTime en Time .

 class Date def to_gm_time to_time(new_offset, :gm) end def to_local_time to_time(new_offset(DateTime.now.offset-offset), :local) end private def to_time(dest, method) #Convert a fraction of a day to a number of microseconds usec = (dest.sec_fraction * 60 * 60 * 24 * (10**6)).to_i Time.send(method, dest.year, dest.month, dest.day, dest.hour, dest.min, dest.sec, usec) end end 

Notez que vous devez choisir entre l’heure locale et l’heure GM / UTC.

Les deux extraits de code ci-dessus proviennent du livre de recettes Ruby de O’Reilly. Leur politique de réutilisation du code le permet.

 require 'time' require 'date' t = Time.now d = DateTime.now dd = DateTime.parse(t.to_s) tt = Time.parse(d.to_s) 

Comme mise à jour de l’état de l’écosystème Ruby, Date , DateTime et Time ont maintenant des méthodes pour convertir les différentes classes. Utiliser Ruby 1.9.2+:

 pry [1] pry(main)> ts = 'Jan 1, 2000 12:01:01' => "Jan 1, 2000 12:01:01" [2] pry(main)> require 'time' => true [3] pry(main)> require 'date' => true [4] pry(main)> ds = Date.parse(ts) => # [5] pry(main)> ds.to_date => # [6] pry(main)> ds.to_datetime => # [7] pry(main)> ds.to_time => 2000-01-01 00:00:00 -0700 [8] pry(main)> ds.to_time.class => Time [9] pry(main)> ds.to_datetime.class => DateTime [10] pry(main)> ts = Time.parse(ts) => 2000-01-01 12:01:01 -0700 [11] pry(main)> ts.class => Time [12] pry(main)> ts.to_date => # [13] pry(main)> ts.to_date.class => Date [14] pry(main)> ts.to_datetime => # [15] pry(main)> ts.to_datetime.class => DateTime 

Malheureusement, les fonctions DateTime.to_time, Time.to_datetime et Time.parse ne conservent pas les informations de fuseau horaire. Tout est converti en fuseau horaire local lors de la conversion. L’arithmétique des dates fonctionne toujours mais vous ne pourrez pas afficher les dates avec leurs fuseaux horaires d’origine. Cette information contextuelle est souvent importante. Par exemple, si je souhaite voir des transactions effectuées pendant les heures de bureau à New York, je préfère probablement les afficher dans leurs fuseaux horaires d’origine, pas dans mon fuseau horaire local en Australie (12 heures avant New York).

Les méthodes de conversion ci-dessous conservent cette information tz.

Pour Ruby 1.8, regardez la réponse de Gordon Wilson . C’est du bon vieux livre de recettes Ruby Cookbook.

Pour Ruby 1.9, c’est légèrement plus facile.

 require 'date' # Create a date in some foreign time zone (middle of the Atlantic) d = DateTime.new(2010,01,01, 10,00,00, Rational(-2, 24)) puts d # Convert DateTime to Time, keeping the original timezone t = Time.new(d.year, d.month, d.day, d.hour, d.min, d.sec, d.zone) puts t # Convert Time to DateTime, keeping the original timezone d = DateTime.new(t.year, t.month, t.day, t.hour, t.min, t.sec, Rational(t.gmt_offset / 3600, 24)) puts d 

Cela imprime les éléments suivants

 2010-01-01T10:00:00-02:00 2010-01-01 10:00:00 -0200 2010-01-01T10:00:00-02:00 

Les informations originales de DateTime, y compris le fuseau horaire, sont conservées.

Amélioration de la solution de Gordon Wilson, voici mon essai:

 def to_time #Convert a fraction of a day to a number of microseconds usec = (sec_fraction * 60 * 60 * 24 * (10**6)).to_i t = Time.gm(year, month, day, hour, min, sec, usec) t - offset.abs.div(SECONDS_IN_DAY) end 

Vous aurez le même temps en UTC, en perdant le fuseau horaire (malheureusement)

De plus, si vous avez ruby ​​1.9, essayez simplement la méthode to_time