tindavid
asked on
Need perl command line program to test if 2 string variable is of date value and compare them
I have 2 lines of text as below:
#!/usr/bin/ksh
record1="Tue Mar 29 00:48:05 2016"
record2="Tue Mar 29 00:48:05 2016"
record1_is_time_record=`pe rl -n ...... ${record1} .....`
record2_is_time_record=`pe rl -n ...... ${record2} .....`
if [ $record1_is_time -eq 1 ] and [ $record2_is_time -eq 1 ]; then
record1_is_eailer_than_rec ord2=`perl -n ....... ${record1} compare with $reocrd2} return 1 is yes else 0..
fi
#!/usr/bin/ksh
record1="Tue Mar 29 00:48:05 2016"
record2="Tue Mar 29 00:48:05 2016"
record1_is_time_record=`pe
record2_is_time_record=`pe
if [ $record1_is_time -eq 1 ] and [ $record2_is_time -eq 1 ]; then
record1_is_eailer_than_rec
fi
Will the dates always be in the format you show in your question? If not, do you know what other formats are possible?
Hmm. Do you want the script in perl or do you want two perl one-liners to check the date format? If just two one-liners, why not do the whole thing in perl? It would actually be simpler.
If all you want is one-liners, I think this should work (I hardly ever call perl from a shell script so the variable syntax may be off or the return may not be correct)...
If all you want is one-liners, I think this should work (I hardly ever call perl from a shell script so the variable syntax may be off or the return may not be correct)...
# these check the format but don't actually check for valid dates
record1_is_time_record=`perl -e "print '${record1}' =~ m{^\w+\s+\w+\d+\s+\d\d:\d\d:\d\d\s+\d{4}$}) ? 1 : 0"`
record2_is_time_record=`perl -e "print '${record2}' =~ m{^\w+\s+\w+\d+\s+\d\d:\d\d:\d\d\s+\d{4}$}) ? 1 : 0"`
if [ $record1_is_time -eq 1 ] and [ $record2_is_time -eq 1 ]; then
# this will be standard cmp comparison output (-1 is record1 is earlier, 0 if equal, 1 if record2 is earlier)
record_compare=`perl -e "use Data::Manip; print Date_Cmp('${record1}', '${record2}')"`
fi
ASKER
record1 and 2 has to be a valid date valid, therefore
record1_is_time_record=`pe rl -e ...` shall return 1 or 0 if it is valid date value
also, our system does not have the Date Library. as below:
Can't locate Data/Manip.pm in @INC (@INC contains: /opt/perl_32/lib/5.8.8/IA6 4.ARCHREV_ 0-thread-m ulti /opt/perl_32/lib/5.8.8 /opt/perl_32/lib/site_perl /5.8.8/IA6 4.ARCHREV_ 0-thread-m ulti /opt/perl_32/lib/site_perl /5.8.8 /opt/perl_32/lib/site_perl /opt/perl_32/lib/vendor_pe rl/5.8.8/I A64.ARCHRE V_0-thread -multi /opt/perl_32/lib/vendor_pe rl/5.8.8 /opt/perl_32/lib/vendor_pe rl .) at -e line 1.
BEGIN failed--compilation aborted at -e line 1.
Can we use some other method to do the comparison ? my shell script will be like this:
#!/usr/bin/ksh
# the information in record can be following type of Date format or other non date string
#
record1="Thu Apr 28 09:53:55 2016" # can be some other rubbish string
record2="Thu Apr 29 10:53:55 2016" # can be some other rubbish string
# these check the format but don't actually check for valid dates
record1_is_time_record=`pe rl -e ....`
record2_is_time_record=`pe rl -e .... `
if [ $record1_is_time -eq 1 ] and [ $record2_is_time -eq 1 ]; then
# this will be standard cmp comparison output (-1 is record1 is earlier, 0 if equal, 1 if record2 is earlier)
record_compare=`perl -e "use Data::Manip; print Date_Cmp('${record1}', '${record2}')"`
fi
record1_is_time_record=`pe
also, our system does not have the Date Library. as below:
Can't locate Data/Manip.pm in @INC (@INC contains: /opt/perl_32/lib/5.8.8/IA6
BEGIN failed--compilation aborted at -e line 1.
Can we use some other method to do the comparison ? my shell script will be like this:
#!/usr/bin/ksh
# the information in record can be following type of Date format or other non date string
#
record1="Thu Apr 28 09:53:55 2016" # can be some other rubbish string
record2="Thu Apr 29 10:53:55 2016" # can be some other rubbish string
# these check the format but don't actually check for valid dates
record1_is_time_record=`pe
record2_is_time_record=`pe
if [ $record1_is_time -eq 1 ] and [ $record2_is_time -eq 1 ]; then
# this will be standard cmp comparison output (-1 is record1 is earlier, 0 if equal, 1 if record2 is earlier)
record_compare=`perl -e "use Data::Manip; print Date_Cmp('${record1}', '${record2}')"`
fi
Is it enough the validate the format of the date or does it need to be validated as a valid date (eg the current regex I suggested would accept "ABC DEF 99 66:77:88 9999" as valid).
Oops. It should have been Date::Manip (not Data::Manip). Can you try the following and let me know if any of them succeed? If any of them work, you can stop (the first 3 would definitely work - the others, I'm just guessing based on the module name).
perl -e 'use Date::Manip'
perl -e 'use Date::Calc'
perl -e 'use DateTime'
perl -e 'use Time::Date'
perl -e 'use Date::Parser'
perl -e 'use Date::Parse'
Oops. It should have been Date::Manip (not Data::Manip). Can you try the following and let me know if any of them succeed? If any of them work, you can stop (the first 3 would definitely work - the others, I'm just guessing based on the module name).
perl -e 'use Date::Manip'
perl -e 'use Date::Calc'
perl -e 'use DateTime'
perl -e 'use Time::Date'
perl -e 'use Date::Parser'
perl -e 'use Date::Parse'
ASKER
Hi Wil,
Very unfortunately, all your suggested test of the library do not work . see the outcome below:
rxngna02[nGens_wk][/home/d ba/oracle/ dtin] >perl -e 'use Date::Manip'
Can't locate Date/Manip.pm in @INC (@INC contains: /opt/perl_32/lib/5.8.8/IA6 4.ARCHREV_ 0-thread-m ulti /opt/perl_32/lib/5.8.8 /opt/perl_32/lib/site_perl /5.8.8/IA6 4.ARCHREV_ 0-thread-m ulti /opt/perl_32/lib/site_perl /5.8.8 /opt/perl_32/lib/site_perl /opt/perl_32/lib/vendor_pe rl/5.8.8/I A64.ARCHRE V_0-thread -multi /opt/perl_32/lib/vendor_pe rl/5.8.8 /opt/perl_32/lib/vendor_pe rl .) at -e line 1.
BEGIN failed--compilation aborted at -e line 1.
rxngna02[nGens_wk][/home/d ba/oracle/ dtin] >perl -e 'use Date::Calc'
Can't locate Date/Calc.pm in @INC (@INC contains: /opt/perl_32/lib/5.8.8/IA6 4.ARCHREV_ 0-thread-m ulti /opt/perl_32/lib/5.8.8 /opt/perl_32/lib/site_perl /5.8.8/IA6 4.ARCHREV_ 0-thread-m ulti /opt/perl_32/lib/site_perl /5.8.8 /opt/perl_32/lib/site_perl /opt/perl_32/lib/vendor_pe rl/5.8.8/I A64.ARCHRE V_0-thread -multi /opt/perl_32/lib/vendor_pe rl/5.8.8 /opt/perl_32/lib/vendor_pe rl .) at -e line 1.
BEGIN failed--compilation aborted at -e line 1.
rxngna02[nGens_wk][/home/d ba/oracle/ dtin] >perl -e 'use DateTime'
Can't locate DateTime.pm in @INC (@INC contains: /opt/perl_32/lib/5.8.8/IA6 4.ARCHREV_ 0-thread-m ulti /opt/perl_32/lib/5.8.8 /opt/perl_32/lib/site_perl /5.8.8/IA6 4.ARCHREV_ 0-thread-m ulti /opt/perl_32/lib/site_perl /5.8.8 /opt/perl_32/lib/site_perl /opt/perl_32/lib/vendor_pe rl/5.8.8/I A64.ARCHRE V_0-thread -multi /opt/perl_32/lib/vendor_pe rl/5.8.8 /opt/perl_32/lib/vendor_pe rl .) at -e line 1.
BEGIN failed--compilation aborted at -e line 1.
rxngna02[nGens_wk][/home/d ba/oracle/ dtin] >perl -e 'use Time::Date'
Can't locate Time/Date.pm in @INC (@INC contains: /opt/perl_32/lib/5.8.8/IA6 4.ARCHREV_ 0-thread-m ulti /opt/perl_32/lib/5.8.8 /opt/perl_32/lib/site_perl /5.8.8/IA6 4.ARCHREV_ 0-thread-m ulti /opt/perl_32/lib/site_perl /5.8.8 /opt/perl_32/lib/site_perl /opt/perl_32/lib/vendor_pe rl/5.8.8/I A64.ARCHRE V_0-thread -multi /opt/perl_32/lib/vendor_pe rl/5.8.8 /opt/perl_32/lib/vendor_pe rl .) at -e line 1.
BEGIN failed--compilation aborted at -e line 1.
rxngna02[nGens_wk][/home/d ba/oracle/ dtin] >perl -e 'use Date::Parser'
Can't locate Date/Parser.pm in @INC (@INC contains: /opt/perl_32/lib/5.8.8/IA6 4.ARCHREV_ 0-thread-m ulti /opt/perl_32/lib/5.8.8 /opt/perl_32/lib/site_perl /5.8.8/IA6 4.ARCHREV_ 0-thread-m ulti /opt/perl_32/lib/site_perl /5.8.8 /opt/perl_32/lib/site_perl /opt/perl_32/lib/vendor_pe rl/5.8.8/I A64.ARCHRE V_0-thread -multi /opt/perl_32/lib/vendor_pe rl/5.8.8 /opt/perl_32/lib/vendor_pe rl .) at -e line 1.
BEGIN failed--compilation aborted at -e line 1.
rxngna02[nGens_wk][/home/d ba/oracle/ dtin] >perl -e 'use Date::Parse'
Can't locate Date/Parse.pm in @INC (@INC contains: /opt/perl_32/lib/5.8.8/IA6 4.ARCHREV_ 0-thread-m ulti /opt/perl_32/lib/5.8.8 /opt/perl_32/lib/site_perl /5.8.8/IA6 4.ARCHREV_ 0-thread-m ulti /opt/perl_32/lib/site_perl /5.8.8 /opt/perl_32/lib/site_perl /opt/perl_32/lib/vendor_pe rl/5.8.8/I A64.ARCHRE V_0-thread -multi /opt/perl_32/lib/vendor_pe rl/5.8.8 /opt/perl_32/lib/vendor_pe rl .) at -e line 1.
BEGIN failed--compilation aborted at -e line 1.
Very unfortunately, all your suggested test of the library do not work . see the outcome below:
rxngna02[nGens_wk][/home/d
Can't locate Date/Manip.pm in @INC (@INC contains: /opt/perl_32/lib/5.8.8/IA6
BEGIN failed--compilation aborted at -e line 1.
rxngna02[nGens_wk][/home/d
Can't locate Date/Calc.pm in @INC (@INC contains: /opt/perl_32/lib/5.8.8/IA6
BEGIN failed--compilation aborted at -e line 1.
rxngna02[nGens_wk][/home/d
Can't locate DateTime.pm in @INC (@INC contains: /opt/perl_32/lib/5.8.8/IA6
BEGIN failed--compilation aborted at -e line 1.
rxngna02[nGens_wk][/home/d
Can't locate Time/Date.pm in @INC (@INC contains: /opt/perl_32/lib/5.8.8/IA6
BEGIN failed--compilation aborted at -e line 1.
rxngna02[nGens_wk][/home/d
Can't locate Date/Parser.pm in @INC (@INC contains: /opt/perl_32/lib/5.8.8/IA6
BEGIN failed--compilation aborted at -e line 1.
rxngna02[nGens_wk][/home/d
Can't locate Date/Parse.pm in @INC (@INC contains: /opt/perl_32/lib/5.8.8/IA6
BEGIN failed--compilation aborted at -e line 1.
Would it work to do the whole script in perl instead of in ksh and calling perl one-liners?
You didn't answer the question at the top of the previous post... Is it enough the validate the format of the date or does it need to be validated as a valid date (eg the current regex I suggested would accept "ABC DEF 99 66:77:88 9999" as valid).
You didn't answer the question at the top of the previous post... Is it enough the validate the format of the date or does it need to be validated as a valid date (eg the current regex I suggested would accept "ABC DEF 99 66:77:88 9999" as valid).
ASKER
it is ok to have it in a perl and then call it from shell with argument.
i would like to have IN 2 arguments and one return value of 1 or 0 when comparing 2 in args.
it is possible that arg1 might not be the date value at all.
however if they were date value, they will have the above date format.
i would like to have IN 2 arguments and one return value of 1 or 0 when comparing 2 in args.
it is possible that arg1 might not be the date value at all.
however if they were date value, they will have the above date format.
If the perl script takes two date arguments, verifies them, and compares them (if both are dates), what should the output be in each case?
I assume you can not install any more Perl modules from CPAN on your system?
Date1 is not a date
Date2 is not a date
Date1 is less than Date2
Date1 is equal to Date2
Date1 is greater than Date2
I assume you can not install any more Perl modules from CPAN on your system?
ASKER
let say sub_time_compare(arg1,arg2 ) return integer if
0 if unable to compare due to either one of the value is non-date value
-X if arg1 is < arg2 X is the number of days
+X if arg1 is > arg2
I will handle if arg1 = arg2 (by assuming they should have the same pattern or string )
0 if unable to compare due to either one of the value is non-date value
-X if arg1 is < arg2 X is the number of days
+X if arg1 is > arg2
I will handle if arg1 = arg2 (by assuming they should have the same pattern or string )
Without the use of any date modules, it will require quite a bit of code. I wasn't able to test this but I think it's correct. It could potentially return an answer that is off by 1 day (per leap year) if the dates are far enough apart and fall "right". If the dates can be before 2000, this will also need some modification.
You would call it from ksh by:
#!/usr/local/bin/perl
use strict;
use warnings;
my %mm = (Jan => 1, Feb => 2, Mar => 3, Apr => 4, May => 5, Jun => 6,
Jul => 7, Aug => 8, Sep => 9, Oct => 10, Nov => 11, Dec => 12);
my $mon = join '|', keys %mm;
my $dom = (Jan => 31, Feb => 28, Mar => 31, Apr => 30, May => 31, Jun => 30,
Jul => 31, Aug => 31, Sep => 30, Oct => 31, Nov => 30, Dec => 31);
my $dow = 'Mon|Tue|Wed|Thu|Fri|Sat|Sun';
my $dt1 = shift or die "Usage: $0 date1 date2\n";
my $dt2 = shift or die "Usage: $0 date1 date2\n";
my (@pt1, @pt2);
if ($dt1 =~ m{^(?:$dow)\s+($mon)\s+(\d+)\s+(\d\d):(\d\d):(\d\d)\s+(\d{4})$}) {
my @pt1 = ($6, $mm{$1}, $2, $3, $4, $5);
if ($pt1[1] <> 2 and $pt1[2] > $dom{$pt1[1]}) {
ret(0);
} elsif ($pt1[1] == 2 and $pt1[2] > 28 + leap($pt1[0])) {
ret(0);
}
} else {
ret(0);
}
if ($dt2 =~ m{^(?:$dow)\s+($mon)\s+(\d+)\s+(\d\d):(\d\d):(\d\d)\s+(\d{4})$}) {
my @pt2 = ($6, $mm{$1}, $2, $3, $4, $5);
if ($pt2[1] <> 2 and $pt2[2] > $dom{$pt2[1]}) {
ret(0);
} elsif ($pt2[1] == 2 and $pt2[2] > 28 + leap($pt2[0])) {
ret(0);
}
} else {
ret(0);
}
my $days1 = ($pt1[0]-2000) * 365 + sum_mon($pt1[1], $pt1[0]) + $pt1[2];
my $days2 = ($pt2[0]-2000) * 365 + sum_mon($pt2[1], $pt2[0]) + $pt2[2];
ret($days2 - $days1);
sub ret {
print $_[0], "\n";
exit;
}
sub leap {
my ($yr) = @_;
if ($yr % 4 == 0 and ($yr % 100 <> 0 or $yr % 400 == 0)) {
return 1;
}
return 0;
}
sub sum_mon {
my ($mon, $yr) = @_;
my $sum = 0;
for my $i (1..$mon) {
$sum += $dom{$mon};
$sum++ if ($mon == 2 and leap($yr) > 0);
}
}
You would call it from ksh by:
ksh_var=`perl_script_name`
[/code]
ASKER
Tried:
say: compare.pl will contains all your code
my.sh has these lines:
date1="Tue Mar 29 00:48:05 2016"
date2="Tue May 03 00:48:05 2016"
the_result=`perl comparedate.pl ${date1} ${date2}`
when execute:
...
...
Useless use of a constant in void context at comparedate.pl line 9.
Useless use of a constant in void context at comparedate.pl line 9.
Useless use of a constant in void context at comparedate.pl line 9.
Useless use of a constant in void context at comparedate.pl line 9.
syntax error at comparedate.pl line 18, near "<>"
Global symbol "%dom" requires explicit package name at comparedate.pl line 18.
Execution of comparedate.pl aborted due to compilation errors.
say: compare.pl will contains all your code
my.sh has these lines:
date1="Tue Mar 29 00:48:05 2016"
date2="Tue May 03 00:48:05 2016"
the_result=`perl comparedate.pl ${date1} ${date2}`
when execute:
...
...
Useless use of a constant in void context at comparedate.pl line 9.
Useless use of a constant in void context at comparedate.pl line 9.
Useless use of a constant in void context at comparedate.pl line 9.
Useless use of a constant in void context at comparedate.pl line 9.
syntax error at comparedate.pl line 18, near "<>"
Global symbol "%dom" requires explicit package name at comparedate.pl line 18.
Execution of comparedate.pl aborted due to compilation errors.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Excellent solution. That is what I needed!