0

I'm not sure if this behaviour is intended, but it seems a bit weird to me. I'm using the code from How do you get DateTime.parse to return a time in your time zone?

require 'date'
estHoursOffset = +10 # Brisbane/Australia
estOffset = Rational(estHoursOffset, 24)

With some times, the DateTime that's returned is a second earlier:

(DateTime.parse("2012-07-15 16:56:00") - (estHoursOffset/24.0)).new_offset(estOffset)
 => #<DateTime: 2012-07-15T16:55:59+10:00 (2456123.788888889,5/12,2299161)> 

But with other times, it seems correct:

(DateTime.parse("2012-07-15 16:16:00") - (estHoursOffset/24.0)).new_offset(estOffset)
 => #<DateTime: 2012-07-15T16:16:00+10:00 (2456123.7611111114,5/12,2299161)>

The program I'm writing only cares about the minutes, which means I'm getting back 16:55 when I want 16:56.

So my questions are;

  • Is this intentional? (If so, is it documented somewhere - I haven't been able to find anything.)
  • Is there a simple way of fixing this programmatically? Since I don't care about seconds,I suppose I could "round up" the DateTimes returned, but it'd be good to know if this could bring up any other problems in edge cases.
Community
  • 1
  • 1
Alex Ghiculescu
  • 7,522
  • 3
  • 25
  • 41

2 Answers2

1

I tried both times ("2012-07-15 16:56:00" & "2012-07-15 16:16:00") and Ruby was always yielding the times parsed initially. I don't know mate how you managed to get 1 sec less; it is a miracle!! Only joking :)

If this still is giving you a hard time try getting the date (& time) - simpler like this..:

require 'date'    
$date = Time.now                #current date/time

puts $date    
puts $date.min                  #if you want to use only the minutes

$date="2012-07-15 16:56:00"     #if you want to parse it yourself

Moving on to your questions:

-No this is not international and it could be intermittent as well. I've tested your code above (+10h Australia) & from my location London, England (+1h). ALWAYS GOT the time parsed; never a second less or more.

Now if you need to round up the seconds so you will be 100% sure that each & every time you are getting the same results..:

def round_up(seconds)
  divisor = 10**Math.log10(seconds).floor
  i = seconds / divisor
  remainder = seconds % divisor
  if remainder == 0
    i * divisor
  else
    (i + 1) * divisor
  end
end

I cannot see why the rounding will cause problems in boundary conditions; as long as you always keep rounding everything! Hope this helps! Good luck mate :)

Xwris Stoixeia
  • 1,831
  • 21
  • 22
  • Thanks for your help. I should point out that the date/time is being read from a database, so I can't use `Time.now`. I'll see if I can replicate the bug more consistently, otherwise I may just have to go with rounding. – Alex Ghiculescu Jul 31 '12 at 22:52
  • What OS are you using? Just tried this on my PC at work and I don't get the original error. Only happens on my Mac. – Alex Ghiculescu Aug 03 '12 at 00:02
1

This is probably because floating point numbers are imprecise - the 10/24.0 you are subtracting cannot be represented exactly.

If instead of subtracting that float you subtracted a rational, ie Rational(estHoursOffset, 24) then you should be ok

Frederick Cheung
  • 83,189
  • 8
  • 152
  • 174