Re: DateTime::Duration 'in_units' does not properly normalize units

2004-12-13 Thread Dave Rolsky
On Mon, 13 Dec 2004, Joshua Hoblitt wrote:
On Mon, 13 Dec 2004, Dave Rolsky wrote:
On Mon, 13 Dec 2004, Joshua Hoblitt wrote:
It looks like the normalization is hosed.
This method, for the nth time, does not convert between units which do not 
have a fixed conversion rate.
Whooo, I seem to have missed the bus here.  Wasn't the entire point of
->in_units so people would stop bitching about the other accessors not doing
what they had been trained to expect?  How is ->in_units possibly useful
otherwise?
It will convert between _convertible_ units:
  years <=> months
  weeks <=> days
  hours <=> minutes
  seconds <=> nanoseconds
I for one am getting really tired of all the complaints about 
DT::Duration. Why don't we just add a bunch of accessors, with really 
verbose names, that return deltas relative to -01-01T00:00:00 and 
document the hell out of the fact that this is what's going on.  e.g.
Something like that sounds reasonable.
->estimated_years
->guessed_months
->imperfect_days,
->imprecise_hours
->loose_minutes,
->rough_seconds
->surmised_nanoseconds
->uncertain_years
->unprecise_months
->unscientific_days
->approximate_hours
->relative_minutes
->seconds_relative_to_0
The names need some work ;)
-dave
/*===
VegGuide.Org
Your guide to all that's veg.
===*/


Re: DateTime::Duration 'in_units' does not properly normalize units

2004-12-13 Thread Yitzchak Scott-Thoennes
On Mon, Dec 13, 2004 at 06:14:12PM -0800, Yitzchak Scott-Thoennes <[EMAIL 
PROTECTED]> wrote:
> On Mon, Dec 13, 2004 at 07:04:23PM -0600, Dave Rolsky <[EMAIL PROTECTED]> 
> wrote:
> > On Mon, 13 Dec 2004, Dave Rolsky wrote:
> > 
> > >>>How can that be sane? So you ask for minutes and you get fractional
> > >>>minutes but you ask for seconds and get zero?
> > >
> > >Cause really it should just blow up when you give it fractional anything.
> > 
> > Or not.  Anyone know of a good way to check that a parameter is one of:
> > 
> >  - an integer
> 
> int($param) != $param  # works even for values greater than max UV

==, not !=  :)

> 
> >  - infinity
> >  - NaN
> 
> $param - $param != 0;  # indicates +/-Inf or NaN
> (differentiate between the two: $param != $param ? "nan" : "infinite")
> 
> > keeping in mind that if I regex a very large number it gets converted to a 
> > string which may be "1.5853e+18"!


Re: DateTime::Duration 'in_units' does not properly normalize units

2004-12-13 Thread Joshua Hoblitt
On Mon, 13 Dec 2004, Tim Jenness wrote:
On Mon, 13 Dec 2004, Dave Rolsky wrote:
Maybe it could be something like DT::Duration::Fractional?  What do others
think?
A variant of Duration that assumes standard lengths for day, minutes, hour
etc, and with a caveat that it will always add seconds when combined with
a DateTime object would be great.
If this is the route to be taken, it should be sufficient to create a 
standard
DateTime::Duration object (instead of a subclass) with the duration expressed
on as seconds/nanoseconds.  Then ->in_units would work as you had expected.
Am I volunteering...?
Are you? :)
Cheers,
-J
--


Re: DateTime::Duration 'in_units' does not properly normalize units

2004-12-13 Thread Joshua Hoblitt
On Mon, 13 Dec 2004, Dave Rolsky wrote:
On Mon, 13 Dec 2004, Joshua Hoblitt wrote:
It looks like the normalization is hosed.
This method, for the nth time, does not convert between units which do not 
have a fixed conversion rate.
Whooo, I seem to have missed the bus here.  Wasn't the entire point of
->in_units so people would stop bitching about the other accessors not doing
what they had been trained to expect?  How is ->in_units possibly useful
otherwise?
I for one am getting really tired of all the complaints about DT::Duration.
Why don't we just add a bunch of accessors, with really verbose names, that
return deltas relative to -01-01T00:00:00 and document the hell out of the
fact that this is what's going on.  e.g.
--
->estimated_years
->guessed_months
->imperfect_days,
->imprecise_hours
->loose_minutes,
->rough_seconds
->surmised_nanoseconds
->uncertain_years
->unprecise_months
->unscientific_days
->approximate_hours
->relative_minutes
->seconds_relative_to_0
.
.
__
I'd also point out that it probably won't work well with non-integer units. 
I'm not sure what'll happen when you try to add 160.2 minutes to a DateTime 
object, but it won't be anything good, I'm sure.

How can that be sane? So you ask for minutes and you get fractional
minutes but you ask for seconds and get zero?
Cause really it should just blow up when you give it fractional anything.
The validation spec doesn't limit the input to integers.  Either the
implementation or the spec needs to be fixed...
--
my %p = validate( @_,
 { years   => { type => SCALAR, default => 0 },
   months  => { type => SCALAR, default => 0 },
   weeks   => { type => SCALAR, default => 0 },
   days=> { type => SCALAR, default => 0 },
   hours   => { type => SCALAR, default => 0 },
   minutes => { type => SCALAR, default => 0 },
   seconds => { type => SCALAR, default => 0 },
   nanoseconds => { type => SCALAR, default => 0 },
   end_of_month => { type => SCALAR, default => undef,
 regex => 
qr/^(?:wrap|limit|preserve)$/ },
 } );
--
Cheers,
-J
--


Re: DateTime::Duration 'in_units' does not properly normalize units

2004-12-13 Thread Dave Rolsky
On Mon, 13 Dec 2004, Tim Jenness wrote:
 Thanks for the reply. So are you saying that DateTime::Duration
shouldn't really be used at all if I have units of fractional anything and
want to convert that to a duration? I'm supposed to convert it first to
hours, minutes and seconds and then instantiate a DateTime::Duration from
that? Shouldn't there be DateTime warnings if that is attempted?
Yes, yes, and yes, it should, but it doesn't.
 What I don't understand is why converting a duration from fractional
hours, minutes and seconds is not a standard part of the module. It would
seem to be an obvious use for it (and I have lots of data sources that use
fractional hours or fractional seconds).
The problem (as I've reiterated many times) is that the number of seconds 
per minute is not fixed, nor are the number of hours per day.

DateTime::Format::Duration does handle fractional hours, minutes and
seconds but I can't see an obvious way to convert a
DateTime::Format::Duration object to a DateTime::Duration object
without saying something convoluted like:
 my $dur = DateTime::Duration->new(
 seconds => DateTime::Format::Duration->new(
 pattern => '%s')->format_duration_from_deltas( hours => 2.67 ))
which can't be the best way of doing this but does result in a Duration
object of 9612.2 sec but now I get:
 hours: 0
 minutes: 0
 seconds: 9612
 nanoseconds: 96120
which also seems bizarre and non-obvious since I would expect
in_units('hours') to return '2'. How come seconds from the constructor
aren't converted to hours and minutes?
See above.
I'm not sure what "fixed conversion rate" means in this context but it
clearly doesn't mean divide seconds by 3600 to get hours.
Yeah, I need to make that clearer.  The problem is that with leap seconds, 
there are a few 3601 second hours out there.

As a related aside. What is wrong with addiing 160.2 minutes to a DateTime
object? It seems to be a perfectly sensible thing to do if it is first
converted to seconds.
If you convert the .2 minutes to seconds first, yes, it is perfectly 
sensible.

Sorry to show my ignorance here but I am extremely confused by the fact
that I can't come up with any sane usage for a Duration object (I realise
that I'm probably being colored by assuming I can switch all my code from
Time::Seconds (part of Time::Piece) to DateTime::Duration with minimal
pain.
DT && DT::Duration are definitely not meant to emulate Time::Piece and 
Time::Seconds.  Time::Seconds is intentionally bogus.  For example, it 
assumes that each year has exactly 365.24225 days!

If you have data that assumes a 3600 second hour (for example TAI based 
data), then you'd have to convert fractional minutes into minutes + 
seconds before creating a new DT::Duration object.  This could be wrapped 
up in a module easily.

Maybe it could be something like DT::Duration::Fractional?  What do others 
think?

-dave
/*===
VegGuide.Org
Your guide to all that's veg.
===*/


Re: DateTime::Duration 'in_units' does not properly normalize units

2004-12-13 Thread Yitzchak Scott-Thoennes
On Mon, Dec 13, 2004 at 07:04:23PM -0600, Dave Rolsky <[EMAIL PROTECTED]> wrote:
> On Mon, 13 Dec 2004, Dave Rolsky wrote:
> 
> >>>How can that be sane? So you ask for minutes and you get fractional
> >>>minutes but you ask for seconds and get zero?
> >
> >Cause really it should just blow up when you give it fractional anything.
> 
> Or not.  Anyone know of a good way to check that a parameter is one of:
> 
>  - an integer

int($param) != $param  # works even for values greater than max UV

>  - infinity
>  - NaN

$param - $param != 0;  # indicates +/-Inf or NaN
(differentiate between the two: $param != $param ? "nan" : "infinite")

> keeping in mind that if I regex a very large number it gets converted to a 
> string which may be "1.5853e+18"!


Re: DateTime::Duration 'in_units' does not properly normalize units

2004-12-13 Thread Dave Rolsky
On Mon, 13 Dec 2004, Dave Rolsky wrote:
How can that be sane? So you ask for minutes and you get fractional
minutes but you ask for seconds and get zero?
Cause really it should just blow up when you give it fractional anything.
Or not.  Anyone know of a good way to check that a parameter is one of:
 - an integer
 - infinity
 - NaN
keeping in mind that if I regex a very large number it gets converted to a 
string which may be "1.5853e+18"!

-dave
/*===
VegGuide.Org
Your guide to all that's veg.
===*/


Re: DateTime::Duration 'in_units' does not properly normalize units

2004-12-13 Thread Dave Rolsky
On Mon, 13 Dec 2004, Joshua Hoblitt wrote:
It looks like the normalization is hosed.
This method, for the nth time, does not convert between units which do not 
have a fixed conversion rate.

I'd also point out that it probably won't work well with non-integer 
units.  I'm not sure what'll happen when you try to add 160.2 minutes to a 
DateTime object, but it won't be anything good, I'm sure.

use DateTime::Duration;
my $dur = DateTime::Duration->new( hours => 2.67 );
print "hours: ",$dur->in_units( 'hours' ), "\n";
Prints 2, as you'd expect
print "minutes: ",  $dur->in_units( 'minutes' ), "\n";
prints 160.2, which is right
print "seconds: ",  $dur->in_units( 'seconds' ), "\n";
prints 0
print "nanoseconds: ",  $dur->in_units( 'nanoseconds' ), "\n";
also 0
How can that be sane? So you ask for minutes and you get fractional
minutes but you ask for seconds and get zero?
Cause really it should just blow up when you give it fractional anything.
-dave
/*===
VegGuide.Org
Your guide to all that's veg.
===*/


DateTime::Duration 'in_units' does not properly normalize units

2004-12-13 Thread Joshua Hoblitt
Hi Tim,
It looks like the normalization is hosed.
Cut 'n Paste-able example:
--
use DateTime::Duration;
my $dur = DateTime::Duration->new( hours => 2.67 );
print "hours: ",$dur->in_units( 'hours' ), "\n";
print "minutes: ",  $dur->in_units( 'minutes' ), "\n";
print "seconds: ",  $dur->in_units( 'seconds' ), "\n";
print "nanoseconds: ",  $dur->in_units( 'nanoseconds' ), "\n";
--
-J
--
On Mon, 13 Dec 2004, Tim Jenness wrote:
perldl> $dur = DateTime::Duration->new( hours => 2.67);
perldl> print $dur->minutes
40.2
perldl> print $dur->seconds
0
How can that be sane? So you ask for minutes and you get fractional
minutes but you ask for seconds and get zero?
 !
Hang on.
perldl> print $dur->in_units( 'minutes' )
160.2
perldl> print $dur->in_units( 'seconds' )
0
perldl>
so clearly in_units() is doing the right thing except that for 'seconds'
it's not working at all
perldl> print $dur->in_units( 'hours' )
2
and neither is hours since that should say 2.67 to be consistent with
minutes returning 160.2.
I'm extremely confused by this seeming inconsistency.
--
Tim Jenness
JAC software
http://www.jach.hawaii.edu/~timj



Re: DateTime::Duration 'in_units' does not properly normalize units

2004-12-13 Thread fglock
I once wrote a module to do this (long before DateTime).
Note that in the second case the result is exact.
Date::Tie is _very_ careful to round errors correctly.

  use Date::Tie;

  tie my %date, 'Date::Tie', frac_hour => 2.67;

  print $date{frac_hour}, "\n";
  print $date{hour}, ":", 
$date{minute}, ":", 
$date{frac_second}, "\n";

  # 02.67
  # 02:40:12.0

  $date{frac_hour} = 2 + 2/3;

  print $date{frac_hour}, "\n";
  print $date{hour}, ":", 
$date{minute}, ":",   
$date{frac_second}, "\n";

  # 02.67
  # 02:40:00.0

- Flavio S. Glock




Re: DateTime::Duration 'in_units' does not properly normalize units

2004-12-13 Thread Tim Jenness
On Mon, 13 Dec 2004, Dave Rolsky wrote:

> On Mon, 13 Dec 2004, Tim Jenness wrote:
> 
> Yeah, I need to make that clearer.  The problem is that with leap seconds, 
> there are a few 3601 second hours out there.
> 

Now it becomes clear.

> > As a related aside. What is wrong with addiing 160.2 minutes to a DateTime
> > object? It seems to be a perfectly sensible thing to do if it is first
> > converted to seconds.
> 
> If you convert the .2 minutes to seconds first, yes, it is perfectly 
> sensible.
> 
> > Sorry to show my ignorance here but I am extremely confused by the fact
> > that I can't come up with any sane usage for a Duration object (I realise
> > that I'm probably being colored by assuming I can switch all my code from
> > Time::Seconds (part of Time::Piece) to DateTime::Duration with minimal
> > pain.
> 
> DT && DT::Duration are definitely not meant to emulate Time::Piece and 
> Time::Seconds.  Time::Seconds is intentionally bogus.  For example, it 
> assumes that each year has exactly 365.24225 days!
> 
> If you have data that assumes a 3600 second hour (for example TAI based 
> data), then you'd have to convert fractional minutes into minutes + 
> seconds before creating a new DT::Duration object.  This could be wrapped 
> up in a module easily.
> 

Yes. Okay, I finally understand where you are coming from.

Sometimes a duration really is a duration (essentially a number of 
seconds that can be represented in standardised days, minutes, hours). Or 
more explicitly, a stopwatch starts and then is stopped. The duration then 
has no concept of leap seconds, can not be rendered in units of 
months, since they vary in length, but can be rendered in standard years.

The leap second only becomes an issue when the duration is combined with 
a DateTime object. If it is a duration from a stopwatch then the real 
thing that matters is the number of seconds. If it is a duration 
consisting of discrete days, minutes, months, years and seconds then these 
have to be treated independently.

> Maybe it could be something like DT::Duration::Fractional?  What do others 
> think?

A variant of Duration that assumes standard lengths for day, minutes, hour 
etc, and with a caveat that it will always add seconds when combined with 
a DateTime object would be great.

Am I volunteering...?

-- 
Tim Jenness
JAC software
http://www.jach.hawaii.edu/~timj



Re: DateTime::Duration 'in_units' does not properly normalize units

2004-12-13 Thread Tim Jenness

Dave,

  Thanks for the reply. So are you saying that DateTime::Duration 
shouldn't really be used at all if I have units of fractional anything and 
want to convert that to a duration? I'm supposed to convert it first to 
hours, minutes and seconds and then instantiate a DateTime::Duration from 
that? Shouldn't there be DateTime warnings if that is attempted?

  What I don't understand is why converting a duration from fractional 
hours, minutes and seconds is not a standard part of the module. It would 
seem to be an obvious use for it (and I have lots of data sources that use 
fractional hours or fractional seconds).

DateTime::Format::Duration does handle fractional hours, minutes and 
seconds but I can't see an obvious way to convert a 
DateTime::Format::Duration object to a DateTime::Duration object
without saying something convoluted like:

  my $dur = DateTime::Duration->new( 
  seconds => DateTime::Format::Duration->new( 
  pattern => '%s')->format_duration_from_deltas( hours => 2.67 ))

which can't be the best way of doing this but does result in a Duration 
object of 9612.2 sec but now I get:

  hours: 0
  minutes: 0
  seconds: 9612
  nanoseconds: 96120

which also seems bizarre and non-obvious since I would expect 
in_units('hours') to return '2'. How come seconds from the constructor 
aren't converted to hours and minutes?

I'm not sure what "fixed conversion rate" means in this context but it 
clearly doesn't mean divide seconds by 3600 to get hours.

As a related aside. What is wrong with addiing 160.2 minutes to a DateTime 
object? It seems to be a perfectly sensible thing to do if it is first 
converted to seconds.

Sorry to show my ignorance here but I am extremely confused by the fact
that I can't come up with any sane usage for a Duration object (I realise
that I'm probably being colored by assuming I can switch all my code from
Time::Seconds (part of Time::Piece) to DateTime::Duration with minimal
pain.

Tim

On Mon, 13 Dec 2004, Dave Rolsky wrote:

> On Mon, 13 Dec 2004, Joshua Hoblitt wrote:
> 
> > It looks like the normalization is hosed.
> 
> This method, for the nth time, does not convert between units which do not 
> have a fixed conversion rate.
> 
> I'd also point out that it probably won't work well with non-integer 
> units.  I'm not sure what'll happen when you try to add 160.2 minutes to a 
> DateTime object, but it won't be anything good, I'm sure.
> 
> > use DateTime::Duration;
> >
> > my $dur = DateTime::Duration->new( hours => 2.67 );
> >
> > print "hours: ",$dur->in_units( 'hours' ), "\n";
> 
> Prints 2, as you'd expect
> 
> > print "minutes: ",  $dur->in_units( 'minutes' ), "\n";
> 
> prints 160.2, which is right
> 
> > print "seconds: ",  $dur->in_units( 'seconds' ), "\n";
> 
> prints 0
> 
> > print "nanoseconds: ",  $dur->in_units( 'nanoseconds' ), "\n";
> 
> also 0
> 
> >> How can that be sane? So you ask for minutes and you get fractional
> >> minutes but you ask for seconds and get zero?
> 
> Cause really it should just blow up when you give it fractional anything.
> 
> 
> -dave
> 
> /*===
> VegGuide.Org
> Your guide to all that's veg.
> ===*/
> 

-- 
Tim Jenness
JAC software
http://www.jach.hawaii.edu/~timj