Paul Hill
Paul Hill

Reputation: 35

Calculate number of days between two dates in Perl

I am using Perl to create a script that will email password expiration notifications.

I have two dates:

  1. The date that the users password was set
  2. The date that the users password will expire (180 days after the password was set)

    use DateTime::Format::Strptime;
    
    my $dt_pattern      = DateTime::Format::Strptime->new( pattern => '%F',);
    my $displayName = $entry->get_value("displayName");
    
    my $pwdLastSet = convertWinFileTimestamp($entry->get_value("pwdLastSet"));
    
    # Determine password expiration date
    my $pwdLastSet_dt = $dt_pattern->parse_datetime($pwdLastSet);
    my $pwdExpirationDate = $pwdLastSet_dt->add( days => $maxPwdAge );
    
    # Days until password expires
    # HELP!!!!!!!
    
    sub convertWinFileTimestamp {
            my $timestamp = shift;
            # Strip off nanoseconds, then adjust date from AD epoch (1601) to UNIX epoch (1970)
            return POSIX::strftime( "%Y-%m-%d",
            localtime( ( $timestamp / 10000000 ) - 11644473600 ) );
    }
    

I cannot figure out how to calculate the difference between the two dates!

Below is the output for each variable:

    pwdLastSet:     2015-02-12
    pwdExpireDate:  2015-08-11T00:00:00

Any help much appreciated...been googling like crazy but I can't figure it out...Thanks!

I tried the following lines of code:

    my $pwdDaysLeft = int(($pwdExpirationDate - $pwdLastSet) / 86400);

but got the following error:

    Only a DateTime::Duration or DateTime object can  be subtracted from a DateTime object. at pwdreminder.pl line 65

Upvotes: 0

Views: 2605

Answers (1)

Dave Cross
Dave Cross

Reputation: 69264

So, we have three dates here:

  • The date that the password was last set. This starts off as a string in the format YYYY-MM-DD stored in $pwdLastSet, but then you parse it into a DateTime object stored in $pwdLastSet_dt.
  • The date that the current password expires. This is calculated by adding $maxPwdAge days to $pwdLastSet_dt, which gives a DateTime object which is then stored in $pwdExpirationDate.
  • The current date. Which, in your current code, you don't calculate.

What you actually want is the difference in days a between the second and third of these two dates. We can ignore the first date as is it only used to calculate the second date. I assume that you're calculating that correctly.

Hopefully, the password expiration date will always be in the future. So the calculation we want to do is:

my $diff = $pwdExpirationDate - $current_date;

As long as both of those are DateTime objects, we'll get a DateTime::Duration object back, which we can then ask for the number of days.

DateTime has a today() method that will give the current date. So our code becomes:

# Use delta_days() to get a duration object that just contains days
my $diff = $pwdExpirationDate->delta_days(DateTime->today);
print $diff->in_units('days');

Upvotes: 3

Related Questions