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

Monks,

I'm trying to tell if a transaction occurred more than 1 day ago. I have a $last_timeout value in the database saved as a timestamp by MySQL in this format:

Tue Oct 23, 2018 - 19:57:12
Perl's DateTime's "now" feature is in this format:
2018-10-24T10:37:03

What is the best way to go about this? All I need to do is subtract one from the other to see if the value is >= 1.

Replies are listed 'Best First'.
Re: Comparing different timestamp formats
by haukex (Archbishop) on Oct 24, 2018 at 20:55 UTC

    Normally, the best thing to do would be to work directly with the database's date/time functions.

    Perl's DateTime's "now" feature is in this format

    Not exactly, that's just the default stringification. Note that DateTime objects can be compared directly, they overload the comparison operators.

    If you're really stuck with parsing a string, my personal favorite module is DateTime::Format::Strptime. Here's one way to go about it:

    use warnings; use strict; use DateTime; use DateTime::Format::Strptime; my $strp = DateTime::Format::Strptime->new(on_error=>'croak', pattern => '%a %b %d, %Y - %H:%M:%S', time_zone => 'UTC'); my $dt = $strp->parse_datetime('Tue Oct 23, 2018 - 19:57:12'); print $dt->strftime('%Y-%m-%d %H:%M:%S %z'), "\n"; my $dt_one_day_ago = DateTime->now->subtract(days=>1); print "$dt is ", $dt < $dt_one_day_ago ? '<' : '>=', " $dt_one_day_ago\n";

    The above takes the time of day into account as well, if that's what you want. Also, make sure to set the time zones correctly!

    (BTW, there is also DateTime::Format::MySQL and DateTime::Format::DBI, although I haven't used these myself.)

Re: Comparing different timestamp formats
by tangent (Parson) on Oct 24, 2018 at 21:59 UTC
    As haukex points out, you can use the database functions to calculate the difference. You can select the interval between now and the timestamp you have like this:
    SELECT TIMESTAMPDIFF( MINUTE, STR_TO_DATE('Tue Oct 23, 2018 - 19:57:12','%a %b %d, %Y - %T'), NOW() );
    That will return the difference in minutes - you can use SECOND as well. In your SQL query you might have something like this:
    SELECT column_name, TIMESTAMPDIFF( SECOND, STR_TO_DATE(column_name,'%a %b %d, %Y - %T'), NOW() ) FROM table;
Re: Comparing different timestamp formats
by 1nickt (Canon) on Oct 24, 2018 at 21:14 UTC

    Hi, I wonder how your MySQL timestamp has that format? By default MySQL timestamps look like '2018-10-24 17:08:00'.

    As ++haukex suggested, the best thing to do is let the DB do that query: after all, that's what it's for. You should easily be able to create an SQL query to fetch the records you're interested in with the DBI.

    For comparison, here's the database table I am working on right now:

    [localhost]:mysql> explain account; +---------------+------------------+------+-----+-------------------+- +----------------------------+ | Field | Type | Null | Key | Default | +Extra | +---------------+------------------+------+-----+-------------------+- +----------------------------+ [redacted] | created_on | timestamp | NO | | CURRENT_TIMESTAMP | + | | modified_on | timestamp | NO | | CURRENT_TIMESTAMP | +on update CURRENT_TIMESTAMP | +---------------+------------------+------+-----+-------------------+- +----------------------------+ 9 rows in set (0.00 sec) [localhost]:mysql> select count(account_id) from account; +-------------------+ | count(account_id) | +-------------------+ | 66 | +-------------------+ 1 row in set (0.00 sec) [localhost]:mysql> select count(account_id) from account where datedif +f(now(), modified_on) >= 1; +-------------------+ | count(account_id) | +-------------------+ | 42 | +-------------------+ 1 row in set (0.00 sec)

    "I'm trying to tell if a transaction occurred more than 1 day ago."

    Note that the granularity of date_diff is one day, so for your query you probably want everything that's not 0 days difference.

    Hope this helps!


    The way forward always starts with a minimal test.