web-dev-qa-db-fra.com

Comment puis-je obtenir le nombre de secondes entre deux DateTimes dans Ruby on Rails

J'ai un code qui fait le suivi du temps pour les employés. Cela crée un compteur pour montrer à l'employé combien de temps ils ont été enregistrés.

C'est le code actuel:

  start_time = Time.parse(self.settings.first_clock_in)
  total_seconds = Time.now - start_time
  hours = (total_seconds/ 3600).to_i
  minutes = ((total_seconds % 3600) / 60).to_i
  seconds = ((total_seconds % 3600) % 60).to_i

Cela fonctionne bien. Mais comme le temps est limité à la plage 1970 - 2038, nous essayons de remplacer toutes les utilisations de temps par DateTimes. Je n'arrive pas à comprendre comment obtenir le nombre de secondes entre deux DateTimes. En les soustrayant, on obtient un Rational que je ne sais pas interpréter, alors qu'en soustrayant Times, on obtient la différence en secondes.

REMARQUE: Depuis Ruby 1.9.2, la limite stricte de temps est supprimée. Cependant, Time est optimisé pour les valeurs comprises entre 1823-11-12 et 2116-02-20.

55
Tilendor

La soustraction de deux DateTimes renvoie le temps écoulé en jours, vous pouvez donc simplement faire:

elapsed_seconds = ((end_time - start_time) * 24 * 60 * 60).to_i
70
David Ma

Ou, plus lisiblement:

diff = datetime_1 - datetime_2
diff * 1.days # => difference in seconds; requires Ruby on Rails

Notez que ce que vous-même ou d’autres chercheurs pouvez réellement rechercher est le suivant:

diff = datetime_1 - datetime_2
Date.day_fraction_to_time(diff) # => [h, m, s, frac_s]
48
Avram Dorfman

Vous pouvez les convertir en floats avec to_f, bien que cela entraîne la perte de précision habituelle associée aux floats. Si vous lancez simplement un entier pendant quelques secondes, il ne devrait pas être assez gros pour vous inquiéter.

Les résultats sont en secondes:

>> end_time.to_f - start_time.to_f
=> 7.39954495429993

>> (end_time.to_f - start_time.to_f).to_i
=> 7

Autrement, vous pourriez envisager d'utiliser to_formatted_s sur l'objet DateTime et de voir si vous pouvez insérer le résultat dans quelque chose que la classe Decimal acceptera, ou simplement le formater en tant qu'heure Unix en tant que chaîne et appeler to_i.

28
Luke

J'utilise Ruby-2.1.4 et pour moi ce qui suit a fonctionné

Time.now - Time.new(2014,11,05,17,30,0)

m'a donné la différence de temps en secondes

reference: Ruby doc

8
Som Poddar

D'autres s'appuient incorrectement sur des fractions ou des fonctions auxiliaires. C'est beaucoup plus simple que ça. DateTime lui-même est un entier inférieur. Voici la manière de Ruby:

stop.to_i - start.to_i

Exemple:

start = Time.now
 => 2016-06-21 14:55:36 -0700
stop = start + 5.seconds
 => 2016-06-21 14:55:41 -0700
stop.to_i - start.to_i
 => 5
8
Amin Ariana

Définir une fonction Ruby comme ceci,

def time_diff(start_time, end_time)
  seconds_diff = (start_time - end_time).to_i.abs

  days = seconds_diff / 86400 
  seconds_diff -= days * 86400

  hours = seconds_diff / 3600  
  seconds_diff -= hours * 3600

  minutes = seconds_diff / 60
  seconds_diff -= minutes * 60

  seconds = seconds_diff

  "#{days} Days #{hours} Hrs #{minutes} Min #{seconds} Sec"
 end

Et appelez cette fonction,

time_diff(Time.now, Time.now-4.days-2.hours-1.minutes-53.seconds)
1
ramya

pourquoi ne pas utiliser le "sec" intégré. Voici un exemple : 

t1 = Time.now.sec 

elapsed_t = Time.now.sec - t1

puts "it took me :  #{elapsed_t} seconds to do something that is useful \n"
0
zee