Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

I can't subtract one DateTime object from another to get a DateTime::Duration in days

by Cody Fendant (Hermit)
on May 10, 2021 at 22:17 UTC ( [id://11132358]=perlquestion: print w/replies, xml ) Need Help??

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

Oh the shame: my date objects weren't actually differing by more than one day because I'm an idiot and assumed that my inputs were what I thought they were! Thanks commenters for forcing me to go back and look at exactly what was in the objects. I leave this here as a memorial, or it can be reaped.

This is a bug in an application I'm working on.

The code creates two DateTime objects and subtracts one from the other to get a DateTime::Duration object.

However the DateTime::Duration object can't return a difference in number of days, which is what I need.

This is actually expected behaviour:


my $dur = DateTime::Duration->new( years => 1, months => 15 ); $dur->in_units('years'); # 2 $dur->in_units('months'); # 27 $dur->in_units( 'years', 'months' ); # (2, 3) $dur->in_units( 'weeks', 'days' ); # (0, 0) !
The last example demonstrates that there will not be any conversion between units which don't have a fixed conversion rate.

I guess my question is, how do I get the difference in days between two DateTime objects?

Updated: The current code just does

my $diff = $dt1 - $dt2;
Where both DateTime objects are specific fixed dates, like one is January 1, 2021 at 10 AM and the other is today at 11 AM. Surely there's a 'fixed conversion rate' in days between those? Note: They were essentially the same day!

I can understand that if I create a duration object with years => 1, months => 15 that's not something where we can be sure of the number of days, but that's not what's happening in my code.

Replies are listed 'Best First'.
Re: I can't subtract one DateTime object from another to get a DateTime::Duration in days
by 1nickt (Canon) on May 10, 2021 at 23:59 UTC

    Hi,

    how do I get the difference in days between two DateTime objects?

    https://metacpan.org/pod/DateTime#$dt-%3Edelta_days($datetime)

    The $dt->delta_days method returns a duration which contains only days.

    $ perl -MDateTime -E 'my $dt = DateTime->new(year=>2021); say DateTime +->now->delta_days($dt)->in_units("days")' 130

    Hope this helps!


    The way forward always starts with a minimal test.
Re: I can't subtract one DateTime objects from each other to get a DateTime::Duration in days
by LanX (Saint) on May 10, 2021 at 23:03 UTC
    you are not showing any code to reproduce the problem, the snippet is just copied from the pod.

    My best guess is that you are requesting "days" from a duration which has "no fixed conversion rate" for days.

    From the docs, just a paragraph after the code you posted ...

    The only conversions possible are:

    years <=> months

    weeks <=> days

    hours <=> minutes

    seconds <=> nanoseconds

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

      I have updated the post to make it more clear what's happening.

      One DateTime object, with a specific date and time, is being subtracted from another specific DateTime object.

        > I have updated the post to make it more clear what's happening.

        no you haven't, please see SSCCE for the next time.

        update

        FWIW: your approach is still wrong and will only sometimes produce correct results.

        See 1nickt's reply with ->delta_days for the correct solution

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

Re: I can't subtract one DateTime object from another to get a DateTime::Duration in days
by cavac (Parson) on May 18, 2021 at 10:37 UTC

    From memory, DateTime is a bit limited in that regard. You can use Date::Manip for complex date math.

    A long, long time ago (in a galaxy unfortunately not far enough away), i wrote "Custom date calculations using Date::Manip", see 11109316

    perl -e 'use Crypt::Digest::SHA256 qw[sha256_hex]; print substr(sha256_hex("the Answer To Life, The Universe And Everything"), 6, 2), "\n";'
Re: I can't subtract one DateTime object from another to get a DateTime::Duration in days
by perlfan (Vicar) on May 11, 2021 at 17:21 UTC
    You almost always never need DateTime and can almost always use strftime from POSIX, in combination with the time functions perl already supports.
      True, you probably never 'need' the power of DateTime. However, it does offer the convenience of a 'swiss-army-knife'. It has always been able to solve my time related problems without the effort of searching for a better tool.
      Bill
        I don't hate DateTime or think less of anyone who does use it, I just use it when I have to. Usually that's never. YMMV
      maybe show some code to back that up?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11132358]
Approved by johngg
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (5)
As of 2024-04-24 06:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found