In the year 2525

J

Jim v. Tess

Is there a reason why Time.local can't handle dates beyond 2038? I know
that's when the number of second since 1970 exceeds 2^32, but can't a
big, strong language like Ruby handle it?

irb(main):004:0> Time.local(2038)
=> Fri Jan 01 00:00:00 Pacific Standard Time 2038


irb(main):005:0> Time.local(2039)
ArgumentError: time out of range
from (irb):5:in `local'
from (irb):5
 
D

David Vallner

--------------enigB9ED8801E7B28C408DD8100D
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Is there a reason why Time.local can't handle dates beyond 2038? I kno= w=20
that's when the number of second since 1970 exceeds 2^32, but can't a=20
big, strong language like Ruby handle it?
=20

Because it uses the underlying platform's time manipulation functions?
(Disclaimer: That's a wild guess.) No point reinventing the wheel in
Ruby. The numbercrunching to process Unix timestamps would probably be
rather sluggish done in Ruby if done in large quantities - and dates /
times are a rather common datatype you need to handle.

Mebbe hack around the issue by providing Ruby replacements for large
timestamps? Then again, maybe that's what the Date / DateTime classes
do. Buggered if I know, I could never remember which one did what.

David Vallner


--------------enigB9ED8801E7B28C408DD8100D
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: OpenPGP digital signature
Content-Disposition: attachment; filename="signature.asc"

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (MingW32)

iD8DBQFFJxm7y6MhrS8astoRAlKgAJ99wQHzJkwFmkUmxNlNKcjFLbKo+wCdGRUa
2k52LUOTc9Y77EHOjUuoMWw=
=Hl6P
-----END PGP SIGNATURE-----

--------------enigB9ED8801E7B28C408DD8100D--
 
K

khaines

Because it uses the underlying platform's time manipulation functions?
Yes.

Mebbe hack around the issue by providing Ruby replacements for large
timestamps? Then again, maybe that's what the Date / DateTime classes
do. Buggered if I know, I could never remember which one did what.

Yes. DateTime uses Rational to represent time. 1 represents a day, not a
second. It can be used with arbitrary dates well outside the range of
Time, but it is MUCH slower. Use Time everywhere one can.


Kirk Haines
 
B

Bill Kelly

From: said:
Yes. DateTime uses Rational to represent time. 1 represents a day, not a
second. It can be used with arbitrary dates well outside the range of
Time, but it is MUCH slower. Use Time everywhere one can.

DateTime sounds nice. As cool as ruby's automatic Fixnum -> Bignum
auto-conversions are, one imagines a date where even someone learning
ruby might be able to specify "puts 2**256" (can already), or
Date.years_ago( -13_700_000_000 ).to_s
=> "Big Bang"


Is it not theoretically possible to make a "fixnum->bignum-like Date",
where it would be fast until its precision was exceeded? Then morph
into a badass DateTime that could handle dinosaurs, and big bangs,
etc.?


With Respect,

Bill
 
S

Suraj N. Kurapati

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Bill said:
DateTime sounds nice. As cool as ruby's automatic Fixnum -> Bignum
auto-conversions are, one imagines a date where even someone learning
ruby might be able to specify "puts 2**256" (can already), or
Date.years_ago( -13_700_000_000 ).to_s
=> "Big Bang"


Is it not theoretically possible to make a "fixnum->bignum-like Date",
where it would be fast until its precision was exceeded? Then morph
into a badass DateTime that could handle dinosaurs, and big bangs, etc.?

Furthermore, what about automatic Float -> BigDecimal conversion?
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (GNU/Linux)

iD8DBQFFJ1FymV9O7RYnKMcRAkU/AKCRnJbfT6yq2kl/TXa2PD77kVEoxgCfVkZH
uZBiltQMjjiPdB2wgNFwDPU=
=mXTx
-----END PGP SIGNATURE-----
 
J

Jonathan Hudson

David said:
Because it uses the underlying platform's time manipulation functions?

And brings interesting portability issues (not only for ruby).

$ irb=> Mon Jan 01 00:00:00 GMT 2525
 
K

Kalman Noel

Jim v. Tess:
irb(main):004:0> Time.local(2038)
=> Fri Jan 01 00:00:00 Pacific Standard Time 2038


irb(main):005:0> Time.local(2039)
ArgumentError: time out of range
from (irb):5:in `local'
from (irb):5

Never rely on future times...

irb> RUBY_PLATFORM
=> "x86_64-linux"

irb> Time.local(2**31-1)
=> Tue Jan 01 00:00:00 CET 2147483647
irb> Time.local(2**31)
=> Wed Jan 01 00:00:00 CET -2147483648

irb> n = 2147485547
=> 2147485547
irb> Time.local(n)
=> Wed Jan 01 00:00:00 CET -2147481749
irb> Time.local(n+1)
ArgumentError: argument out of range
from (irb):70:in `local'
from (irb):70
from :0

Kalman
 
D

David Vallner

--------------enig472AFB8D74DD789718E9A45B
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Furthermore, what about automatic Float -> BigDecimal conversion?

Wouldn't that only be possible if the processor reports if an IEEE
floating-point conversion / operation was inprecise / innacurate (can't
for the heck of it remember which term applies here.)

Even if that was the case, that means that say a floating point division
would take would take one attempt, report that, convert the floating
point numbers to BigDecimals, and then perform the division in Ruby.
This isn't something I'd like happening in code even casually working
with floating point numbers for performance reasons. Though it's a valid
Shiny Thing to put as an optional mode of operation.

David Vallner


--------------enig472AFB8D74DD789718E9A45B
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: OpenPGP digital signature
Content-Disposition: attachment; filename="signature.asc"

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (MingW32)

iD8DBQFFJ30yy6MhrS8astoRAiaZAJwM8yiJj5fV2eZgIjQT6Zgr1Q4OSACcDUN/
frO0UODd6vnkiBdUx/i9Ot4=
=S/Q4
-----END PGP SIGNATURE-----

--------------enig472AFB8D74DD789718E9A45B--
 
V

Vincent Fourmond

David said:
Wouldn't that only be possible if the processor reports if an IEEE
floating-point conversion / operation was inprecise / innacurate (can't
for the heck of it remember which term applies here.)

Even if that was the case, that means that say a floating point division
would take would take one attempt, report that, convert the floating
point numbers to BigDecimals, and then perform the division in Ruby.

I think that basically every operation on a number which doesn't have
a natural writing in base 2 would trigger the conversion. That is,
unless you do 2 * 0.5, you'll switch automatically to BigDecimal. Bad
idea. Why don't you use BigDecimal systematically, if you're really
worried about precision ?

Cheers !

Vince
 
S

Suraj N. Kurapati

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Vincent said:
I think that basically every operation on a number which doesn't have
a natural writing in base 2 would trigger the conversion. That is,
unless you do 2 * 0.5, you'll switch automatically to BigDecimal. Bad
idea. Why don't you use BigDecimal systematically, if you're really
worried about precision ?

Well, manually applying BigDecimal wherever necessary for
performance reasons feels like programming in C (remember floats and
doubles? /me vomits).

When I was learning Ruby, I absolutely *loved* the fact that Fixnum
automatically spills into Bignum and vice versa... good riddance to
short, int, long, and long long! Just think of how beneficial this
conceptual abstraction (I don't care how many bits it occupies, I
just want to use this integer!) has been to your code and mode of
thinking. If Ruby didn't have this, we would be manually checking
sizes, upcasting, and downcasting Fixnums and Bignums everywhere. :-(

I don't care so much about performance; rather, I want to write code
quickly and elegantly using conceptual abstractions. If I really
need performance, I will profile the code and re-write the slow
parts in C.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (GNU/Linux)

iD8DBQFFJ8ZvmV9O7RYnKMcRAi5NAJ47Kby2Bo6OaZU2LWBeEJ8iJ9Sh+wCcDzqz
eAlA7MMIlci1VyaBmojAcL8=
=A4po
-----END PGP SIGNATURE-----
 
D

David Vallner

--------------enig8C6C42CEB1626E5D079965E7
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Well, manually applying BigDecimal wherever necessary for
performance reasons feels like programming in C (remember floats and
doubles? /me vomits).
=20

Yes, but there's performance losses, and performance losses. For the
fixnum -> bignum conversion, there's a whole of two cutover numbers
where you have to convert from one to the other. For a Float ->
BigDecimal conversion, there's probably an infinity of them.

Also:

---

require 'bigdecimal'
require 'benchmark'

N =3D 1000000

Benchmark.bmbm { |test|
test.report("Float") {
for i in 1..N
Math::pI / Math::E
end
}

test.report("BigDecimal") {
for i in 1..N
BigDecimal.new(String(Math::pI)) /
BigDecimal(String(Math::E))
end
}
}

---

Rehearsal ----------------------------------------------
Float 0.937000 0.000000 0.937000 ( 0.969000)
BigDecimal 30.594000 0.093000 30.687000 ( 30.922000)
------------------------------------ total: 31.624000sec

user system total real
Float 1.031000 0.000000 1.031000 ( 1.015000)
BigDecimal 30.453000 0.078000 30.531000 ( 30.766000)

---

That's a slowdown by a factor of 30. Which means simple decimal maths in
Ruby could be slower by at least a factor of 20 on average by my wild
guess. That's without the overhead of verifying if the result of a maths
operation can be represented in IEEE floats. Besides, even BigDecimals
lose precision eventually, and they don't have nearly as many use cases
as either arbitrary-size integers (that help prevent counter overflows),
or fast floating-point maths.

For a more "interesting" benchmark, let's see less trivial number crunchi=
ng.

---

require 'bigdecimal'
require 'bigdecimal/math'
require 'benchmark'

N =3D 100000

include BigMath

Benchmark.bmbm { |test|
test.report("Float") {
for i in 1..N
Math.log(Math::pI) / Math.log(Math::E)
end
}

test.report("BigDecimal") {
for i in 1..N
log(BigDecimal(String(Math::pI)), 20) /
log(BigDecimal(String(Math::E)), 20)
end
}
}

---

Rehearsal ----------------------------------------------
Float 0.172000 0.000000 0.172000 ( 0.203000)
BigDecimal 278.641000 0.656000 279.297000 (279.422000)
----------------------------------- total: 279.469000sec

user system total real
Float 0.218000 0.000000 0.218000 ( 0.203000)
BigDecimal 276.266000 0.625000 276.891000 (286.234000)

---

That's a slowdown by a factor of roughly 1267... I don't need profiling
to see this would kill even casual use of nontrivial amounts of
numbercrunching.
I don't care so much about performance; rather, I want to write code
quickly and elegantly using conceptual abstractions. If I really
need performance, I will profile the code and re-write the slow
parts in C.

Which turns your proposal into "Let's make Ruby behave not like C,
crippling speed, so that everyone ends up rewriting maths code in C". I
fail to see the gain. As I said, the automagical conversion is somewhere
on my list of Potential Shiny Things. I doubt it's an essential feature
for, well, anyone. And it would be actively harmful to make it default
behaviour, or ever alter the behaviour to this in a library released
into the wild.

David Vallner


--------------enig8C6C42CEB1626E5D079965E7
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: OpenPGP digital signature
Content-Disposition: attachment; filename="signature.asc"

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (MingW32)

iD8DBQFFJ9Ooy6MhrS8astoRArHcAJ9xjZnfDk1gh8LzT6/dZuQOesUA2gCfc2GW
avQb9bvGAKx5uhnXjYQ7jRM=
=JjY4
-----END PGP SIGNATURE-----

--------------enig8C6C42CEB1626E5D079965E7--
 
V

Vincent Fourmond

Suraj said:
I don't care so much about performance; rather, I want to write code
quickly and elegantly using conceptual abstractions. If I really
need performance, I will profile the code and re-write the slow
parts in C.

I completely agree with this approach. However, you will find that you
can't have floats that behave the way you would like... For
Fixnum/Bignum the deal is really simple: when something goes too big,
you switch from one to the other. Simply because if not, you get an
arithmetic overflow. But for floats, it is completely different. I don't
think you'll ever get a too big float (do you often manipulate numbers
over 10**300 or below 10**-300 ?). But if you want to switch to
BigDecimals when you lose precision, then you should do it from the
beginning, because unless you compute with numbers in base 2, you always
lose precision with a float operation...

So my answer is: use BigDecimals, if you're worried about precision
(but that still will not take care of all the problems; maybe Rationnal
is what you're looking for ?).

Cheers !

Vince

PS: yes, I know it sucks to have to take care manually of the things in C...
 
C

Charles Oliver Nutter

Jim said:
Is there a reason why Time.local can't handle dates beyond 2038? I know
that's when the number of second since 1970 exceeds 2^32, but can't a
big, strong language like Ruby handle it?

It works in JRuby...would that be considered an incompatibility, or is
it an ok diversion from the C impl?

irb(main):001:0> Time.local(2038)
=> Fri Jan 01 00:00:00 CST 2038
irb(main):002:0> Time.local(2039)
=> Sat Jan 01 00:00:00 CST 2039
irb(main):003:0> Time.local(10191)
=> Sat Jan 01 00:00:00 CST 10191
 
C

Charles Oliver Nutter

Charles said:
It works in JRuby...would that be considered an incompatibility, or is
it an ok diversion from the C impl?

irb(main):001:0> Time.local(2038)
=> Fri Jan 01 00:00:00 CST 2038
irb(main):002:0> Time.local(2039)
=> Sat Jan 01 00:00:00 CST 2039
irb(main):003:0> Time.local(10191)
=> Sat Jan 01 00:00:00 CST 10191

In light of the x86_64 responses, I'd wager it's ok :) I don't know what
the performance is like, though, for Java's Date compared to the POSIX
calls.
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: In the year 2525"

|Jim v. Tess wrote:
|> Is there a reason why Time.local can't handle dates beyond 2038? I know
|> that's when the number of second since 1970 exceeds 2^32, but can't a
|> big, strong language like Ruby handle it?
|
|It works in JRuby...would that be considered an incompatibility, or is
|it an ok diversion from the C impl?

I think it is an OK diversion.

matz.
 
A

ara.t.howard

|It works in JRuby...would that be considered an incompatibility, or is
|it an ok diversion from the C impl?

I think it is an OK diversion.

you'll put us all out of work matz - think of all the contracts in 2037!

-a
 
D

dblack

Hi --

Hi,

In message "Re: In the year 2525"

|Jim v. Tess wrote:
|> Is there a reason why Time.local can't handle dates beyond 2038? I know
|> that's when the number of second since 1970 exceeds 2^32, but can't a
|> big, strong language like Ruby handle it?
|
|It works in JRuby...would that be considered an incompatibility, or is
|it an ok diversion from the C impl?

I think it is an OK diversion.

It's definitely an incompatibility, though, in the sense that it has
the potential to create a category of programs that will run under
JRuby but not (original) Ruby.


David

--
David A. Black | (e-mail address removed)
Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org
 
M

M. Edward (Ed) Borasky

you'll put us all out of work matz - think of all the contracts in 2037!

-a

Ah, but that assumes people will still be using 32-bit machines then. I
don't know if I'll be around to collect, but I'd bet a tidy sum that the
"default" home computer in 2030 will be a 128-bit multicore machine.

I'm not willing to predict how much RAM or disk space it will have, or
what the operating systems, programming languages and applications will
look like. But just like the supercomputers of the mid-1980s are dwarfed
by today's laptops, I don't think it's a stretch to think that 20 years
from now, the laptops will dwarf today's supercomputers.

I guess I need to take good care of myself. :)
 
D

Devin Mullins

It's definitely an incompatibility, though, in the sense that it has
the potential to create a category of programs that will run under
JRuby but not (original) Ruby.
Except on 64-bit machines.

And don't forget that there are plenty of platform-incompatibilities
already (particularly for Windows): Kernel#open, fork, shell expansion
differences when using Kernel#`, FileUtils.ln, gems that require gcc &
friends, etc.

Ruby doesn't wall the programmer off from the OS, and so it has to pay
the price that Ruby programs might not work on every OS by default. It
has the benefit of giving the programmer more freedom, though (say, for
example, to <a href="http://jakarta.apache.org/commons/io/">copy a
frickin' file</a>), and that's good.

That said, it'd be nice if the difference between (and reason for) Time,
Date, and DateTime were made a little clearer in the docs. *touches nose*

Devin
 
B

Bill Kelly

From: said:
It's definitely an incompatibility, though, in the sense that it has
the potential to create a category of programs that will run under
JRuby but not (original) Ruby.

I did have a surprise like this, just a couple days ago:

Linux:

$ ruby -ve 'p Time.now.strftime("%F %T")'
ruby 1.8.4 (2005-12-24) [i686-linux]
"2006-10-07 19:05:01"

Windows:
ruby -ve 'p Time.now.strftime("%F %T")'
ruby 1.8.4 (2005-12-24) [i386-mswin32]
" "


Regards,

Bill
 

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,982
Messages
2,570,189
Members
46,735
Latest member
HikmatRamazanov

Latest Threads

Top