DateTime new_offset unexpected results

G

Greg Go

Hello, everybody:

I'm new to ruby, but I'm pretty sure this isn't a problem with me.

I'm running ruby 1.8.6 on Windows XP, and using NetBeans as my IDE.

My application reads the rise, transit and set times for the sun at my
location from a spreadsheet. The spreadsheet provides the date and time
as an astronomical julian date that I then use to create a number of
DateTime objects.

I manually check for Daylight Savings Time by creating two more DateTime
objects, one for DST start, the other for DST end as class variables.

I have a method that returns the local time of the event as another
DateTime object created with DateTime's new_offset method.

Here's the code that actually determines whether it's DST or not, and
creates the local time object accordingly:

offset = Rational(-7,24)
if (@jd > @@dstStart) && (@jd < @@dstEnd)
offset = Rational(-6,24)
end
@ld = @jd.new_offset(offset)

@jd is the julian date of the event.

The problem is this:
For some events, @ld is one hour off.

Here's an example:
@jd.to_s #=> 2008-03-09T13:24:59+00:00
@ld.to_s #=> 2008-03-09T06:24:59-06:00

In my book, 13 - 6 = 7, not 6.

I've tried with different offset values, as well:
@jd.to_s #=> 2008-03-09T13:24:59+00:00
@ld.to_s #=> 2008-03-09T08:24:59-05:00 - Correct

@jd.to_s #=> 2008-03-09T13:24:59+00:00
@ld.to_s #=> 2008-03-09T05:24:59-08:00 - Correct

So, it appears that it's only when the offset is -6.

This is only happening to some events. However, all events are instances
the same class, with the code above.

I've used this base class to do the same thing with lunar events, with
no problem.

This seems like a bug to me.

Any ideas as to what's going on?

Thanks for your help!
Greg
 
T

Todd Benson

Hello, everybody:

I'm new to ruby, but I'm pretty sure this isn't a problem with me.

I'm running ruby 1.8.6 on Windows XP, and using NetBeans as my IDE.

My application reads the rise, transit and set times for the sun at my
location from a spreadsheet. The spreadsheet provides the date and time
as an astronomical julian date that I then use to create a number of
DateTime objects.

I manually check for Daylight Savings Time by creating two more DateTime
objects, one for DST start, the other for DST end as class variables.

I have a method that returns the local time of the event as another
DateTime object created with DateTime's new_offset method.

Here's the code that actually determines whether it's DST or not, and
creates the local time object accordingly:

offset = Rational(-7,24)
if (@jd > @@dstStart) && (@jd < @@dstEnd)
offset = Rational(-6,24)
end
@ld = @jd.new_offset(offset)

@jd is the julian date of the event.

The problem is this:
For some events, @ld is one hour off.

Here's an example:
@jd.to_s #=> 2008-03-09T13:24:59+00:00
@ld.to_s #=> 2008-03-09T06:24:59-06:00

In my book, 13 - 6 = 7, not 6.

I've tried with different offset values, as well:
@jd.to_s #=> 2008-03-09T13:24:59+00:00
@ld.to_s #=> 2008-03-09T08:24:59-05:00 - Correct

@jd.to_s #=> 2008-03-09T13:24:59+00:00
@ld.to_s #=> 2008-03-09T05:24:59-08:00 - Correct

So, it appears that it's only when the offset is -6.

This is only happening to some events. However, all events are instances
the same class, with the code above.

I've used this base class to do the same thing with lunar events, with
no problem.

This seems like a bug to me.

Any ideas as to what's going on?

Output your dstStart and dstEnd values while you run the program
(inside the "if" construct). That should give you some idea. I don't
think this is a bug in the new_offset method, but who knows? You said
"some" events. Is it always at the same time of day? A certain time
of year?

Todd
 
G

Greg Go

Todd said:
Output your dstStart and dstEnd values while you run the program
(inside the "if" construct). That should give you some idea. I don't
think this is a bug in the new_offset method, but who knows? You said
"some" events. Is it always at the same time of day? A certain time
of year?


Todd:

Thanks for your reply.
dstStart and dstEnd are class variables, and are constants representing
the UT of DST start and end for the United States for 2008. All of my
astronomical data are in UT, so that works out for me.

I have a container object, day, that utilizes an array to wrangle my
event objects. The array has three event objects in it:
0 - rise
1 - transit
2 - set

It's only the rise object for this invocation of the day class that
fails, and only for DST times.

In addition, the code works well for another very simmilar application.

Referring to (and expanding a bit on) my original post (snipped from the
event class' code):

offset = Rational(-7,24)
if (@jd > @@dstStart) && (@jd < @@dstEnd)
offset = Rational(-6,24)
end
@ld = @jd.new_offset(offset)

@jd.to_s #=> 2008-03-09T13:24:59+00:00
@ld.to_s #=> 2008-03-09T06:24:59-06:00
^^^^^^
!!!!!!

It's my understanding that 13:24:59 offset by -6 hours should result in
7:24:59, not 6:24:59. The @ld instance seems to be confused?

But, these seem to be ok:

offset = Rational(-7,24)
if (@jd > @@dstStart) && (@jd < @@dstEnd)
offset = Rational(-5,24) # Changed for debugging
end
@ld = @jd.new_offset(offset)

@jd.to_s #=> 2008-03-09T13:24:59+00:00
@ld.to_s #=> 2008-03-09T08:24:59-05:00 - Correct



offset = Rational(-7,24)
if (@jd > @@dstStart) && (@jd < @@dstEnd)
offset = Rational(-8,24) # Changed for debugging
end
@ld = @jd.new_offset(offset)

@jd.to_s #=> 2008-03-09T13:24:59+00:00
@ld.to_s #=> 2008-03-09T05:24:59-08:00 - Correct

Sorry about the lack of actual code -- I don't want to post my pile of
noobish fugly code, unless I have to ;) -- but I will if it's helpful.

Thanks!
Greg
 
T

Todd Benson

Todd:

Thanks for your reply.
dstStart and dstEnd are class variables, and are constants representing
the UT of DST start and end for the United States for 2008. All of my
astronomical data are in UT, so that works out for me.

I have a container object, day, that utilizes an array to wrangle my
event objects. The array has three event objects in it:
0 - rise
1 - transit
2 - set

It's only the rise object for this invocation of the day class that
fails, and only for DST times.

And only with Rational(-6, 24) during the rise event?
In addition, the code works well for another very simmilar application.

Referring to (and expanding a bit on) my original post (snipped from the
event class' code):

offset = Rational(-7,24)
if (@jd > @@dstStart) && (@jd < @@dstEnd)
offset = Rational(-6,24)
end
@ld = @jd.new_offset(offset)

Try (#'s mark the additional/changed lines)...

offset = Rational(-7, 24)
puts "dstStart before IF: " << @@dstStart ###
puts "dstEnd before IF: " << @@dstEnd ###
if (@jd > @@dstStart) && (@jd < @@dstEnd)
puts "dstStart after IF: " << @@dstStart ###
puts "dstEnd after IF: " << @@dstEnd ###
offset = Rational(-6, 24)
end
@ld = @jd.new_offset(offset)

puts @jd ###
puts @ld ###

and see what you get for the rise event (just out of curiosity).

Todd
 
D

Dirk Traulsen

Hi Greg!

Am 8 Jan 2008 um 6:05 hat Greg Go geschrieben:
@jd.to_s #=> 2008-03-09T13:24:59+00:00
@ld.to_s #=> 2008-03-09T06:24:59-06:00
^^^^^^
!!!!!!

It's my understanding that 13:24:59 offset by -6 hours should result
in
7:24:59, not 6:24:59. The @ld instance seems to be confused?

It looks like the reason could be the error that I found:

http://rubyforge.org/tracker/?func=detail&atid=1698&aid=14540&
group_id=426

It is a rounding error inside Numeric#divmod, which I found while
inquiring a similar error in date. This bug was confirmed for 1.8.6 and
is fixed (for future versions). If you compile Ruby yourself, this
patch could fix your problem too.

Hope this helps
Dirk
 
G

Greg Go

Todd said:
And only with Rational(-6, 24) during the rise event?

Try (#'s mark the additional/changed lines)...

offset = Rational(-7, 24)
puts "dstStart before IF: " << @@dstStart ###
puts "dstEnd before IF: " << @@dstEnd ###
if (@jd > @@dstStart) && (@jd < @@dstEnd)
puts "dstStart after IF: " << @@dstStart ###
puts "dstEnd after IF: " << @@dstEnd ###
offset = Rational(-6, 24)
end
@ld = @jd.new_offset(offset)

puts @jd ###
puts @ld ###

and see what you get for the rise event (just out of curiosity).

Todd

Todd:

Although I'm not sure what this proves, I did this, and the two class
variables (@@dstStart, @@dstEnd) didn't change. I'm unclear as to where
you're going with this -- am I missing something with the way that ruby
handles class variables?

Thanks!
Greg
 
G

Greg Go

Dirk said:
Hi Greg!

Am 8 Jan 2008 um 6:05 hat Greg Go geschrieben:


It looks like the reason could be the error that I found:

http://rubyforge.org/tracker/?func=detail&atid=1698&aid=14540&
group_id=426

It is a rounding error inside Numeric#divmod, which I found while
inquiring a similar error in date. This bug was confirmed for 1.8.6 and
is fixed (for future versions). If you compile Ruby yourself, this
patch could fix your problem too.

Hope this helps
Dirk

Dirk:

Building ruby myself is a little outside my comfort zone. In my opinion,
one of the major strengths of interpreted languages is that I can avoid
the compilation process, which I find to be tedious and difficult.

Some questions:
Is the bug fix included in 1.9.0?

If not, is there any way at all to work around the problem? I've tried a
number of things, but nothing seems to help.


Thanks!
Greg
 
T

Todd Benson

Todd:

Although I'm not sure what this proves, I did this, and the two class
variables (@@dstStart, @@dstEnd) didn't change. I'm unclear as to where
you're going with this -- am I missing something with the way that ruby
handles class variables?

Simple. Just wanted to see if your dstStart and dstEnd vars were
correct, and if, in fact, you were actually entering the if condition.

It's probably the bug that was mentioned, but I can't reproduce your error.

Todd
 
G

Greg Go

Todd said:
Simple. Just wanted to see if your dstStart and dstEnd vars were
correct, and if, in fact, you were actually entering the if condition.

It's probably the bug that was mentioned, but I can't reproduce your
error.

Todd

Todd:

Ah, I see. What I was doing to confirm that I had entered the test
condition was changing the value of offset to, for example
Rational(-8,24), and Rational(-5,24).

I'll see if I can work up a test case and post it, just to be complete.

Thanks!
Greg
 
T

Todd Benson

By this last statement, I meant if you were entering the if condition
during rise event with -6.
Ah, I see. What I was doing to confirm that I had entered the test
condition was changing the value of offset to, for example
Rational(-8,24), and Rational(-5,24).

I'll see if I can work up a test case and post it, just to be complete.

You don't have to get super crazy :). Do whatever you think will
help. Like I said, I don't see the same error on my system, but I
also don't have your data (your code might have changed the class
variables before the if statement during the "rise" event is what I
was thinking).

Todd
 
G

Greg Go

Todd said:
By this last statement, I meant if you were entering the if condition
during rise event with -6.



You don't have to get super crazy :). Do whatever you think will
help. Like I said, I don't see the same error on my system, but I
also don't have your data (your code might have changed the class
variables before the if statement during the "rise" event is what I
was thinking).

Todd

Todd, et al:

This demonstrates the bug:


@ut = DateTime.new!(2454535.05902777)

# According to http://aa.usno.navy.mil/data/docs/JulianDate.php:
# JD 2454535.05902 is CE 2008 March 09 13:24:59.3 UT

puts @ut.to_s #=> 2008-03-09T13:24:59+00:00

(4..8).each do |i|
puts @ut.new_offset(Rational(-i,24))
end

# 2008-03-09T09:24:59-04:00
# 2008-03-09T08:24:59-05:00
# 2008-03-09T06:24:59-06:00 <- Should be 2008-03-09T07:24:59-06:00
# 2008-03-09T06:24:59-07:00
# 2008-03-09T05:24:59-08:00


Thanks,
Greg
 
T

Todd Benson

Todd, et al:

This demonstrates the bug:


@ut = DateTime.new!(2454535.05902777)

# According to http://aa.usno.navy.mil/data/docs/JulianDate.php:
# JD 2454535.05902 is CE 2008 March 09 13:24:59.3 UT

puts @ut.to_s #=> 2008-03-09T13:24:59+00:00

(4..8).each do |i|
puts @ut.new_offset(Rational(-i,24))
end

# 2008-03-09T09:24:59-04:00
# 2008-03-09T08:24:59-05:00
# 2008-03-09T06:24:59-06:00 <- Should be 2008-03-09T07:24:59-06:00
# 2008-03-09T06:24:59-07:00
# 2008-03-09T05:24:59-08:00

March 9 at (6 - 6) is when your clock changed at midnight.

Todd
 
T

Todd Benson

On Jan 10, 2008 9:59 PM, Todd Benson
March 9 at (6 - 6) is when your clock changed at midnight.

Todd

Alright ... before anyone gets a chance to call me an idiot, this
works (in the US) ...


require 'date'
ut = DateTime.civil( 2007, 3, 9, 13, 24 )

puts ut.to_s

(4..8).each do |e|
puts ut.new_offset( Rational(-e, 24) )
end


Todd
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,276
Messages
2,571,384
Members
48,072
Latest member
FaustoBust

Latest Threads

Top