Time out of range when selecting from database?

R

Ron M

Why does Time allow such a limited set of years:

irb> Time.mktime('2205-01-01')
ArgumentError: time out of range

This especially annoying when other classes like DBI use
the Time class, and when a 200-year-lease in a database
throws an exception when loaded by Ruby.

irb(main):028:0> dbh.select_all("select begin_date,end_date from leases")
ArgumentError: time out of range
from /usr/lib/ruby/site_ruby/1.8/dbi/sql.rb:60:in `gm'
from /usr/lib/ruby/site_ruby/1.8/dbi/sql.rb:60:in `as_timestamp'
from /usr/lib/ruby/site_ruby/1.8/DBD/Pg/Pg.rb:777:in `as_timestamp'
from /usr/lib/ruby/site_ruby/1.8/dbi/sql.rb:80:in `coerce'
from /usr/lib/ruby/site_ruby/1.8/DBD/Pg/Pg.rb:395:in `convert'
from /usr/lib/ruby/site_ruby/1.8/DBD/Pg/Pg.rb:755:in `fill_array'
from (irb):28:in `each_with_index'
from /usr/lib/ruby/site_ruby/1.8/DBD/Pg/Pg.rb:754:in `fill_array'
from /usr/lib/ruby/site_ruby/1.8/DBD/Pg/Pg.rb:707:in `fetchrow'
from /usr/lib/ruby/site_ruby/1.8/DBD/Pg/Pg.rb:644:in `fetch'
from /usr/lib/ruby/site_ruby/1.8/dbi/dbi.rb:1155:in `fetch_all'
from /usr/lib/ruby/site_ruby/1.8/dbi/dbi.rb:1154:in `fetch_all'
from /usr/lib/ruby/site_ruby/1.8/dbi/dbi.rb:919:in `fetch_all'
from /usr/lib/ruby/site_ruby/1.8/dbi/dbi.rb:675:in `select_all'
from /usr/lib/ruby/site_ruby/1.8/dbi/dbi.rb:645:in `execute'
from /usr/lib/ruby/site_ruby/1.8/dbi/dbi.rb:671:in `select_all'
from (irb):28irb(main):029:0>

Surely if ruby can transparently do math between Fixnum's and Bignum's,
it could handle transparent math outside the range of the Time class,
can't it?
 
K

Kirk Haines

Why does Time allow such a limited set of years:

irb> Time.mktime('2205-01-01')
ArgumentError: time out of range

This especially annoying when other classes like DBI use
the Time class, and when a 200-year-lease in a database
throws an exception when loaded by Ruby.

See the discussion about converting between Time and DateTime. Time uses
seconds since the start of 1970, and basically just uses the underlying C
functions for most of what it does. So, you are pretty limited in your date
range. Within the range supported, Time is fast because it uses a simple
unit and C functions underneath, but that loses flexibility.

DateTime uses the Rational class, and can handle whatever date you want to
give it. It is a lot slower than Time, though.

Now, for DBI, there are a few issues with DBI currently with regard to dates.
One of them is what you are describing. DBI actually stores dates internally
in one of three different classes, and internally it stores years, months,
dates, hours, minutes, seconds separately, so it'll support any date that you
want. But the code that creates a DBI::Timestamp for you uses the Time
class, which is where your error came from.

A patch for DBI to to deal with this gracefully looks like it should not be
too hard, though. I'll see if I can whip one up sometime in the next day or
two.


Kirk Haines
 

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
473,774
Messages
2,569,598
Members
45,149
Latest member
Vinay Kumar Nevatia0
Top