Date arithmetic advise/improvement - using stat ... calling the Perlscript from a UNIX script

--bcaec51b2071510a57049e229092
Content-Type: text/plain; charset=ISO-8859-1

Hi all,

Just want to know what improvement can be done with the code below if any. I
am sure a lot of improvement/changes is required. I will be calling this
script from a UNIX script, i.e.timediff=`timediff.pl $file`, so $file will
be passed to the Perl script. It's probably a good idea to check whether the
$file is passed and if so, check if the file exists or not.

Most of the print lines are just for testing/purposes. Ultimately, what am
wanting to assign to the timediff variable in the UNIX script is the string
"( 5 weeks, 3 days, 10:16:1 )" but only if the file is x days old. Do I need
to have something like a return timediff_detail command in the Perl script?

FYI, I've decided to use stat instead of Perl Date modules because each
server have different Date modules installed, some have Date::Manip, some
have Date::Calc etc. so using stat is the best option that I have.

Any advise/help will be much appreciated. Thanks.


-----
Code for timediff.pl so far
-----

#!/usr/bin/perl

#$today = localtime();
$today_epoch = time();
$today = localtime($today_epoch);
[at] date_fields = split(" ",$today);
$day=$date_fields[2];
$month=uc($date_fields[1]);
$year=$date_fields[4];

[at] time_fields = split(":",$date_fields[3]);
$hour=$time_fields[0];
$minute=$time_fields[1];
$second=$time_fields[2];

print "Today is ==> $today \n";
print "DAY is ==> $day ... \n";
print "MONTH is ==> $month ... \n";
print "YEAR is ==> $year ... \n";
print "HOUR is ==> $hour ... \n";
print "MINUTE is ==> $minute ... \n";
print "SECOND is ==> $second ... \n";

my ( $dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
$atime, $mtime, $ctime,
$blksize, $blocks )
= stat("x1.pl");

print "\n";
print "< ====================================== > \n";
print "Output from stat ... \n";
print " dev => $dev \n";
print " ino => $ino \n";
print " mode => $mode \n";
print " nlink => $nlink \n";
print " uid => $uid \n";
print " gid => $gid \n";
print " rdev => $rdev \n";
print " size => $size \n";
print " atime => " . localtime($atime) . " ==> \n";
print " mtime => " . localtime($mtime) . " ==> \n";
print " mtime - not localtime => " . $mtime . " ==> \n";
print " ctime => " . localtime($ctime) . " ==> \n";
print " blksize => $blksize \n";
print " blocks => $blocks \n";
print "< ====================================== > \n";
print "\n";

$difference=$today_epoch-$mtime;

$seconds = $difference % 60;
$difference = ($difference - $seconds) / 60;
$minutes = $difference % 60;
$difference = ($difference - $minutes) / 60;
$hours = $difference % 24;
$difference = ($difference - $hours) / 24;
$days = $difference % 7;
$weeks = ($difference - $days) / 7;

print "Age of x1.pl is: \n";
print "( $weeks weeks, $days days, $hours:$minutes:$seconds ) \n";
print "\n";

exit 0;

--------------
Sample Output:
--------------

Today is ==> Fri Mar 11 02:56:22 2011
DAY is ==> 11 ...
MONTH is ==> MAR ...
YEAR is ==> 2011 ...
HOUR is ==> 02 ...
MINUTE is ==> 56 ...
SECOND is ==> 22 ...

< ====================================== >
Output from stat ...
dev => 84148225
ino => 7975633
mode => 33248
nlink => 1
uid => 103
gid => 101
rdev => 0
size => 629
atime => Fri Mar 11 01:07:26 2011 ==>
mtime => Mon Jan 31 16:40:21 2011 ==>
mtime - not localtime => 1296445221 ==>
ctime => Thu Feb 10 19:09:46 2011 ==>
blksize => 8192
blocks => 8
< ====================================== >

Age of x1.pl is:
( 5 weeks, 3 days, 10:16:1 )

--bcaec51b2071510a57049e229092--
newbie01 perl [ Do, 10 März 2011 16:33 ] [ ID #2056418 ]

Re: Date arithmetic advise/improvement - using stat ... calling thePerl script from a UNIX script

On 11-03-10 10:33 AM, newbie01 perl wrote:
> #!/usr/bin/perl
>
> #$today = localtime();
> $today_epoch = time();
> $today = localtime($today_epoch);

my [at] today = localtime( $today_epoch ); # When in list context,
localtime returns an array that can be use with strftime

> [at] date_fields = split(" ",$today);
> $day=$date_fields[2];
> $month=uc($date_fields[1]);
> $year=$date_fields[4];
>
> [at] time_fields = split(":",$date_fields[3]);
> $hour=$time_fields[0];
> $minute=$time_fields[1];
> $second=$time_fields[2];
>
> print "Today is ==> $today \n";

print strftime( "%A\n", [at] today );
# etc.

See:
perldoc POSIX and search for /strftime/
man strftime or http://www.manpagez.com/man/3/strftime/


--
Just my 0.00000002 million dollars worth,
Shawn

Confusion is the first step of understanding.

Programming is as much about organization and communication
as it is about coding.

The secret to great software: Fail early & often.

Eliminate software piracy: use only FLOSS.

--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
Shawn H Corey [ Do, 10 März 2011 16:42 ] [ ID #2056419 ]

Re: Date arithmetic advise/improvement - using stat ... calling thePerl script from a UNIX script

On 10/03/2011 15:33, newbie01 perl wrote:
> Hi all,
>
> Just want to know what improvement can be done with the code below if any. I
> am sure a lot of improvement/changes is required. I will be calling this
> script from a UNIX script, i.e.timediff=`timediff.pl $file`, so $file will
> be passed to the Perl script. It's probably a good idea to check whether the
> $file is passed and if so, check if the file exists or not.
>
> Most of the print lines are just for testing/purposes. Ultimately, what am
> wanting to assign to the timediff variable in the UNIX script is the string
> "( 5 weeks, 3 days, 10:16:1 )" but only if the file is x days old. Do I need
> to have something like a return timediff_detail command in the Perl script?
>
> FYI, I've decided to use stat instead of Perl Date modules because each
> server have different Date modules installed, some have Date::Manip, some
> have Date::Calc etc. so using stat is the best option that I have.
>
> Any advise/help will be much appreciated. Thanks.
>
>
> -----
> Code for timediff.pl so far
> -----
>
> #!/usr/bin/perl
>
> #$today = localtime();
> $today_epoch = time();
> $today = localtime($today_epoch);
> [at] date_fields = split(" ",$today);
> $day=$date_fields[2];
> $month=uc($date_fields[1]);
> $year=$date_fields[4];
>
> [at] time_fields = split(":",$date_fields[3]);
> $hour=$time_fields[0];
> $minute=$time_fields[1];
> $second=$time_fields[2];
>
> print "Today is ==> $today \n";
> print "DAY is ==> $day ... \n";
> print "MONTH is ==> $month ... \n";
> print "YEAR is ==> $year ... \n";
> print "HOUR is ==> $hour ... \n";
> print "MINUTE is ==> $minute ... \n";
> print "SECOND is ==> $second ... \n";
>
> my ( $dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
> $atime, $mtime, $ctime,
> $blksize, $blocks )
> = stat("x1.pl");
>
> print "\n";
> print "< ======================================> \n";
> print "Output from stat ... \n";
> print " dev => $dev \n";
> print " ino => $ino \n";
> print " mode => $mode \n";
> print " nlink => $nlink \n";
> print " uid => $uid \n";
> print " gid => $gid \n";
> print " rdev => $rdev \n";
> print " size => $size \n";
> print " atime => " . localtime($atime) . " ==> \n";
> print " mtime => " . localtime($mtime) . " ==> \n";
> print " mtime - not localtime => " . $mtime . " ==> \n";
> print " ctime => " . localtime($ctime) . " ==> \n";
> print " blksize => $blksize \n";
> print " blocks => $blocks \n";
> print "< ======================================> \n";
> print "\n";
>
> $difference=$today_epoch-$mtime;
>
> $seconds = $difference % 60;
> $difference = ($difference - $seconds) / 60;
> $minutes = $difference % 60;
> $difference = ($difference - $minutes) / 60;
> $hours = $difference % 24;
> $difference = ($difference - $hours) / 24;
> $days = $difference % 7;
> $weeks = ($difference - $days) / 7;
>
> print "Age of x1.pl is: \n";
> print "( $weeks weeks, $days days, $hours:$minutes:$seconds ) \n";
> print "\n";
>
> exit 0;
>
> --------------
> Sample Output:
> --------------
>
> Today is ==> Fri Mar 11 02:56:22 2011
> DAY is ==> 11 ...
> MONTH is ==> MAR ...
> YEAR is ==> 2011 ...
> HOUR is ==> 02 ...
> MINUTE is ==> 56 ...
> SECOND is ==> 22 ...
>
> < ======================================>
> Output from stat ...
> dev => 84148225
> ino => 7975633
> mode => 33248
> nlink => 1
> uid => 103
> gid => 101
> rdev => 0
> size => 629
> atime => Fri Mar 11 01:07:26 2011 ==>
> mtime => Mon Jan 31 16:40:21 2011 ==>
> mtime - not localtime => 1296445221 ==>
> ctime => Thu Feb 10 19:09:46 2011 ==>
> blksize => 8192
> blocks => 8
> < ======================================>
>
> Age of x1.pl is:
> ( 5 weeks, 3 days, 10:16:1 )

You must always 'use strict; use warnings;' at the start of any Perl
program. They will make it much easier to find most trivial bugs.

It would simplify things a lot if you used the -M operator to establish
the age of the file. See 'perldoc -f -X'.

The program below does what you want.

HTH,

Rob


use strict;
use warnings;

my $file = 'x1.pl';

my $age = -M $file;

my $d = int $age;
$age = ($age - $d) * 24;
my $h = int $age;
$age = ($age - $h) * 60;
my $m = int $age;
$age = ($age - $m) * 60;
my $s = int $age;

my $w = int($d / 7);
$d %= 7;

printf "Age of %s is:\n( %d weeks, %d days, %d:%02d:%02d )\n", $file, $w, $d, $h, $m, $s;

__END__

--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
Rob Dixon [ Do, 10 März 2011 18:19 ] [ ID #2056420 ]

Re: Date arithmetic advise/improvement - using stat ... calling thePerl script from a UNIX script

On 10/03/2011 23:13, newbie01 perl wrote:
> On Fri, Mar 11, 2011 at 6:19 AM, Rob Dixon <rob.dixon [at] gmx.com
>> On 10/03/2011 15:33, newbie01 perl wrote:
>>>
>>> Just want to know what improvement can be done with the code
>>> below if any. I am sure a lot of improvement/changes is required.
>>> I will be calling this script from a UNIX script,
>>> i.e.timediff=`timediff.pl <http://timediff.pl> $file`, so $file
>>> will be passed to the Perl script. It's probably a good idea to
>>> check whether the $file is passed and if so, check if the file
>>> exists or not.
>>>
>>> Most of the print lines are just for testing/purposes.
>>> Ultimately, what am wanting to assign to the timediff variable in
>>> the UNIX script is the string "( 5 weeks, 3 days, 10:16:1 )" but
>>> only if the file is x days old. Do I need to have something like
>>> a return timediff_detail command in the Perl script?
>>>
>>> FYI, I've decided to use stat instead of Perl Date modules
>>> because each server have different Date modules installed, some
>>> have Date::Manip, some have Date::Calc etc. so using stat is the
>>> best option that I have.
>>>
>>> Any advise/help will be much appreciated. Thanks.
>>>
>>>
>>> -----
>>> Code for timediff.pl <http://timediff.pl> so far
>>> -----
>>>
>>> #!/usr/bin/perl
>>>
>>> #$today = localtime();
>>> $today_epoch = time();
>>> $today = localtime($today_epoch);
>>> [at] date_fields = split(" ",$today);
>>> $day=$date_fields[2];
>>> $month=uc($date_fields[1]);
>>> $year=$date_fields[4];
>>>
>>> [at] time_fields = split(":",$date_fields[3]);
>>> $hour=$time_fields[0];
>>> $minute=$time_fields[1];
>>> $second=$time_fields[2];
>>>
>>> print "Today is ==> $today \n";
>>> print "DAY is ==> $day ... \n";
>>> print "MONTH is ==> $month ... \n";
>>> print "YEAR is ==> $year ... \n";
>>> print "HOUR is ==> $hour ... \n";
>>> print "MINUTE is ==> $minute ... \n";
>>> print "SECOND is ==> $second ... \n";
>>>
>>> my ( $dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
>>> $atime, $mtime, $ctime,
>>> $blksize, $blocks )
>>> = stat("x1.pl <http://x1.pl>");
>>>
>>> print "\n";
>>> print "< ======================================> \n";
>>> print "Output from stat ... \n";
>>> print " dev => $dev \n";
>>> print " ino => $ino \n";
>>> print " mode => $mode \n";
>>> print " nlink => $nlink \n";
>>> print " uid => $uid \n";
>>> print " gid => $gid \n";
>>> print " rdev => $rdev \n";
>>> print " size => $size \n";
>>> print " atime => " . localtime($atime) . " ==> \n";
>>> print " mtime => " . localtime($mtime) . " ==> \n";
>>> print " mtime - not localtime => " . $mtime . " ==> \n";
>>> print " ctime => " . localtime($ctime) . " ==> \n";
>>> print " blksize => $blksize \n";
>>> print " blocks => $blocks \n";
>>> print "< ======================================> \n";
>>> print "\n";
>>>
>>> $difference=$today_epoch-$mtime;
>>>
>>> $seconds = $difference % 60;
>>> $difference = ($difference - $seconds) / 60;
>>> $minutes = $difference % 60;
>>> $difference = ($difference - $minutes) / 60;
>>> $hours = $difference % 24;
>>> $difference = ($difference - $hours) / 24;
>>> $days = $difference % 7;
>>> $weeks = ($difference - $days) / 7;
>>>
>>> print "Age of x1.pl <http://x1.pl> is: \n";
>>> print "( $weeks weeks, $days days, $hours:$minutes:$seconds ) \n";
>>> print "\n";
>>>
>>> exit 0;
>>>
>>> Sample Output:
>>> [snip]
>>> Age of x1.pl <http://x1.pl> is:
>>> ( 5 weeks, 3 days, 10:16:1 )
>>
>> You must always 'use strict; use warnings;' at the start of any Perl
>> program. They will make it much easier to find most trivial bugs.
>>
>> It would simplify things a lot if you used the -M operator to establish
>> the age of the file. See 'perldoc -f -X'.
>>
>> The program below does what you want.
>>
>> use strict;
>> use warnings;
>>
>> my $file = 'x1.pl';
>>
>> my $age = -M $file;
>>
>> my $d = int $age;
>> $age = ($age - $d) * 24;
>> my $h = int $age;
>> $age = ($age - $h) * 60;
>> my $m = int $age;
>> $age = ($age - $m) * 60;
>> my $s = int $age;
>>
>> my $w = int($d / 7);
>> $d %= 7;
>>
>> printf "Age of %s is:\n( %d weeks, %d days, %d:%02d:%02d )\n",
>> $file, $w, $d, $h, $m, $s;
>>
>> __END__
>
> Thanks a lot for the code ... am embarrassed on how many lines you've
> cut it down to :-)

(Please bottom-post your responses on this list. Thanks.)

That's fine - I have saved a lot of code by using -M instead of stat(),
and your code had many lines of comments and diagnostics whereas mine
had none :)

> I can use warn with the -M right in case the filename supplied as an
> argument does not exist?

-M just returns undef if the file doesn't exist - it doesn't throw a
warning. So you can write

my $age = -M $file or die "Unable to establish age of $file: $!";

I'm afraid my home isn't on a Unix system so I can't help with how to
get the string out to a shell script variable, but that should be
trivial. Unfortunately I can't comment either on whether this is the
best solution, but I am sure others can help.

By the way, if you release your program together with a Perl module in
the same directory it will run fine, although it will have to be a
Perl-only module to ensure that it runs on a variety of platforms.

Cheers,

Rob


--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
Rob Dixon [ Fr, 11 März 2011 02:03 ] [ ID #2056443 ]
Perl » gmane.comp.lang.perl.beginners » Date arithmetic advise/improvement - using stat ... calling the Perlscript from a UNIX script

Vorheriges Thema: Permission bit translator?
Nächstes Thema: multidimensional array check