简体   繁体   中英

Compare timestamp from string with the current system day and turn bad status if it's less than 5 days

I want to compare timestamp from string with the current system day and turn bad status if it's less than 5 days of the current system day, what I mean for example have those dates:

20150705
20150911

I'm wondering how to compare them with the current system date and to show output like that if the current system time is 11 Sep 2015:

20150705 bad
20150911 good

You can use string comparison for YYYYMMDD strings. date handles human readable dates with -d :

#!/bin/bash
old=20150905
new=201510017
good=20150911

before=$(date -d 'today - 5 days' +%Y%m%d)
after=$(date -d 'today + 5 days' +%Y%m%d)
echo $before - $after

for date in $old $new $good ; do
    if [[ $before < $date && $date < $after ]] ; then
        echo $date in the interval
    else
        echo $date outside of the interval
    fi
done

Try using convertion of the date string to unix time, eg

cur_date=$(date +"%s");
cat data_file | while read line;
do
   lineDate=$(date -d "$line" +"%s");
   diff=$(expr $cur_date - $lineDate);
   if [ "$diff" -gt 432000 ];
       then echo $line " bad";
   else
       echo $line " good";
   fi;
done

In Perl, you can use DateTime module to perform operations on Dates.You can easily subtract dates If you get two dates into DateTime object.

To convert earlier dates into DateTime , parse those dates using DateTime::Format::Strptime and then, subtract it from today's date.

So, overall this script will do your job:

#!/usr/bin/perl
use strict;
use warnings;
use DateTime;
use DateTime::Format::Strptime;

my @dates = ( "20150911", "20150705", "20150710" );
my $strp = DateTime::Format::Strptime->new( pattern => '%Y%m%d' ); # parse
my $today = DateTime->today; # get today's date

foreach (@dates) {
    my $mydate = $strp->parse_datetime($_);
    my $sub    = $today->subtract_datetime($mydate)->{'days'};
    if ( $sub > 5 ) {
        print "$_ bad\n";
    }
    else {
        print "$_ good\n";
    }
}

Time::Piece has been included in the standard Perl distribution since 5.10.0 in 2007.

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

use Time::Piece;
use Time::Seconds;

my $now = localtime;

while (<DATA>) {
  chomp;
  my $then = Time::Piece->strptime($_, '%Y%m%d');

  my $status = 'bad';
  if ($now - $then < 5 * ONE_DAY) {
    $status = 'good';
  }

  say "$_ $status";
}

__DATA__
20150705
20150911

You can also use Time::Local for this, which is built-in and converts arbitrary time & date values into epoch time for comparison:

#!/usr/bin/perl --
use warnings;
use strict;

# compare string dates against the current date
# and output each one with a 'bad' or 'good' label

use Time::Local;

while (<DATA>) {
    chomp;

    my $this_time = timelocal(0,0,12,                   # time (dst-compliant)
                              substr($_, -2),           # mday
                              substr($_, 4, 2) - 1,     # month
                              substr($_, 0, 4) - 1900); # year

    print "$_ ", (time() - $this_time <= (86400 * 5) ? 'good' : 'bad'), "\n";
}

__DATA__
20150705
20150911

Output:

$ perl script.pl 
20150705 bad
20150911 good
$ 

Note however that this solution wouldn't be 100% with the time. In other words, it relies on five 24-hour periods of time, rather than five actual calendar days.

Try:

#!/bin/bash

TODAY=`date +%s`
FIVE_DAYS=$((5 * 24 * 60 * 60))

for d in '20150705' '20150911'; do
    t=`date -d $d +%s`
    seconds=$((TODAY - t))
    [ $seconds -gt $FIVE_DAYS ] && result=bad || result=good
    echo "$d $result"
done

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM