views:

720

answers:

3

I've got code that does time tracking for employees. It creates a counter to show the employee how long they have been clocked in for.

This is the current code:

  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

This works fine. But because Time is limited to the range of 1970 - 2038 we are trying to replace all Time uses with DateTimes. I can't figure out how to get the number of seconds between two DateTimes. Subtracting them yields a Rational which I don't know how to interpret, whereas subtracting Times yields the difference in seconds.

+1  A: 

You can convert them to floats with to_f, though this will incur the usual loss of precision associated with floats. If you're just casting to an integer for whole seconds it shouldn't be big enough to be a worry.

The results are in seconds:

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

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

Otherwise, you could look at using to_formatted_s on the DateTime object and seeing if you can coax the output into something the Decimal class will accept, or just formatting it as plain Unix time as a string and calling to_i on that.

Luke
+4  A: 

Subtracting two DateTimes returns the elapsed time in days, so you could just do:

elapsed_seconds = ((end_time - start_time) * 24 * 60 * 60).to_i
David Ma
Ah, I knew it returned it in days, I didn't know that this would include fractions of a day as well.Thanks.
Tilendor
+1  A: 

or, more readably,

diff = datetime_1 - datetime_2 diff * 1.days # => difference in seconds

note, what you or some other searchers might really be looking for is this:

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

Avram Dorfman
you might want to make your code lines formatted. Just put 4 spaces at the beginning of each line to make that line code formatted.
Tilendor