thor has asked for the wisdom of the Perl Monks concerning the following question:

Greetings all, I've been working with Date::Calc a bit recently, and was a little thrown off when I tried to pass in a fractional hour to things like Add_Delta_DHMS. For instance:
#want 1.1 hours from now print join(" ",Add_Delta_DHMS(Today_and_Now, 0, 1.1, 0, 0); print join(" ",Add_Delta_DHMS(Today_and_Now, 0, 1, 0, 0); #prints the same thing!!!
I've come up with a hack that given a floating point number like 1.1, returns the hours, minutes, and seconds.
sub hms { my ($hours) = @_; my $minutes = ($hours - int($hours)) * 60; my $seconds = ($minutes - int($minutes)) * 60; return(int($hours), int($minutes), int($seconds)); }
Is there a better way?

thor

Replies are listed 'Best First'.
Re: Fractional times in Date::Calc
by liz (Monsignor) on Aug 12, 2003 at 18:48 UTC
    Looking at the code in Code.xs
    void DateCalc_Add_Delta_DHMS(year,month,day, hour,min,sec, Dd,Dh,Dm,Ds) Z_int year Z_int month Z_int day Z_int hour Z_int min Z_int sec Z_long Dd Z_long Dh Z_long Dm Z_long Ds
    sorts of indicates why you can't use fractional parameters. ;-(

    If you really want, you could write a routine that would take fractional day, hour, minute and second(?) parameters, and put that subroutine "in front of" the existing subroutine. A sort of non-object oriented subclassing ;-). Or, if you are sure that your "day", "minute" and "second" fields are always 0, use your solution:

    print join(" ",Add_Delta_DHMS(Today_and_Now, 0, hms(1.1));
    but I would find that pretty yucky and poorly maintainable.

    Hope this helps.

    Liz

Re: Fractional times in Date::Calc
by fglock (Vicar) on Aug 13, 2003 at 02:15 UTC

    You could use a module that supports fractional time.

    use Date::Tie; tie my %d, 'Date::Tie'; print " $d{hour}:$d{minute}:$d{second} \n"; $d{frac_hour} += 1.1; print " $d{hour}:$d{minute}:$d{second} \n"; 02:22:04 03:28:04
Re: Fractional times in Date::Calc
by Cody Pendant (Prior) on Aug 12, 2003 at 23:43 UTC
    I must say I sympathise with the module here. The idea of the "fractional hour" is an inherently ambiguous one and would certainly lead to problems for someone, somewhere in the future. I'd say it's to their credit that it handles it gracefully by making the 1.1 into a 1.

    I think your solution is the right way -- pre-process ambiguous information into a form that is acceptable to the module.



    ($_='kkvvttuubbooppuuiiffssqqffssmmiibbddllffss') =~y~b-v~a-z~s; print
      I don't see how a fractional hour is ambiguous. Would there be a different way to interpret "1.25 hours" other than "1 hour and 15 minutes"? The only other way I could see interpreting that string would be to have it mean "1 hour and 25 minutes", that that's what 1:25 is for...:)

      thor

      Update: Corrected last sentence so that it actually makes sense

        Would there be a different way to interpret "1.25 hours" other than "1 hour and 15 minutes"?

        Well obviously, one hour and twenty-five minutes.

        You've got a system which is not decimal-based, and you're using it with decimals.



        ($_='kkvvttuubbooppuuiiffssqqffssmmiibbddllffss') =~y~b-v~a-z~s; print