0

In Perl, how can I get time-stamp of a file and check is this today or not?

toolic
  • 57,801
  • 17
  • 75
  • 117
AlexPham
  • 311
  • 2
  • 4
  • 16
  • 4
    What have you tried? Show us your code and tell us what result you're expecting and how it differs from what your code provides. – Grant McLean Aug 08 '16 at 09:32
  • Please check the link http://www.perlmonks.org/?node=How%20do%20I%20get%20a%20file%27s%20timestamp%20in%20perl%3F – Arijit Panda Aug 08 '16 at 09:38
  • 3
    @Arijit: Please don't link to PerlMonks' copy of the FAQ. It's really old and outdated (and it says that at the top of the page!) The version at [perldoc.perl.org](http://perldoc.perl.org/) will always be up to date. [How do I get a file's timestamp in perl?](http://perldoc.perl.org/perlfaq5.html#How-do-I-get-a-file%27s-timestamp-in-perl?). – Dave Cross Aug 08 '16 at 10:05

4 Answers4

3

I would (probably) use -M:

http://perldoc.perl.org/functions/-X.html

-M Script start time minus file modification time, in days.

This means you can do:

if ( -M $filename < 1 ) { 
    #if file is less than a day old
}

This of course, only applies relative to script start, rather than right now so isn't suitable for long running scripts.

Sobrique
  • 52,974
  • 7
  • 60
  • 101
  • 2
    "Modified less than a day ago" isn't quite the same thing as "modified today". – Dave Cross Aug 08 '16 at 10:35
  • You can set `-M` in relation to `$^T` which is the starting time of the script, i.e. `my $mtime_abs = $^T + (-M $filename);`. But it's still true what @DaveCross says. – PerlDuck Aug 08 '16 at 12:44
2

If helps if you show us exactly what you have tried and what problems you are having.

You can use File::stat to get information about a file.

use File::stat;
my $stat = stat($file);

You can get three different timestamps by calling three different methods on the $stat object.

my $ctime = $stat->ctime; # inode change time
my $atime = $stat->atime; # last access time
my $mtime = $stat->mtime; # last modification time

I think you probably want $mtime, but I can't be sure. Each of these variables contain the time as the number of seconds since your system's epoch (almost certainly 00:00 on 1st Jan 1970).

You can convert these epoch values into useful objects using Time::Piece.

use Time::Piece;
my $file_date = localtime($mtime);

And you can compare that with the current date.

if ($file_date->date eq localtime->date) {
  # file was created today
}
Dave Cross
  • 68,119
  • 3
  • 51
  • 97
  • Nice. Easier than fiddling around with localtime/timelocal. 'sudo cpan -i Time::Piece' to install. – gaoithe Aug 08 '16 at 11:11
  • 1
    No need to install it. Time::Piece has been a part of the standard Perl installation since Perl 5.10 (in 2007). – Dave Cross Aug 08 '16 at 11:13
  • On older machines may need to install. I had to do it for redhat fc19. perl 5 version 16. – gaoithe Aug 08 '16 at 11:39
  • Time::Piece - object-oriented - is definitely the thing to use - much simpler. But I see also had to install it for CentOS7 7.2.1511 (2015). fc19 is 2013. This Q interesting: http://stackoverflow.com/questions/2049735/how-can-i-tell-if-a-perl-module-is-core-or-part-of-the-standard-install Time::Piece is in core modules here: http://perldoc.perl.org/index-modules-T.html – gaoithe Aug 08 '16 at 11:58
  • 1
    That's because of Red Hat's deliberately broken standard Perl installation. If you're using Centos (or RHEL) 6 or greater then rather than installing individual modules, you should `yum install perl-core` to fix your Perl installation. More information in [this old blog post](http://perlhacks.com/2012/08/a-cautionary-tale/). – Dave Cross Aug 08 '16 at 12:00
0
  1. Read about File::stat and get timestamp of file. How do I get a file's last modified time in Perl?
use File::stat;
 # we don't need anything but mtime
 # my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
 #    $atime, $mtime, $ctime, $blksize, $blocks) = stat($filename);
my $ts = stat($filename)->mtime;
print "ts:$ts";
print " date/time " . localtime($ts) . "\n";

ts:1469028287 date/time Wed Jul 20 16:24:47 2016

Oh look. mtime is a big number. How many . . minutes / hours / days / years is that ? (dc is a command-line calculator.)

$ dc
1469028287
60/p
24483804
60/p
408063
24/p
17002
356.25/p
47

47 years. (gained/lost some time up there with the integer division using dc). Now (Mon 8 Aug 10:58ish 2016) - 46(where 46 =ishahem= 47) years = 1/1/1970 00:00:00 = the unix date/time stamp epoch.

  1. Read about localtime, get 'now' time, get times from midnight to midnight for today. http://perldoc.perl.org/functions/localtime.html http://www.perlhowto.com/working_with_date_time How do I use Perl's localtime with print to get the timestamp? Note the value of year from localtime is 116 (116 years since 1900). Note the value of month from localtime is 7 (7 for August. yes because 0 = January, 1 = Feb, e.t.c.).
# localtime returns array or string depending on context.
my $time = localtime;
my @time = localtime;
print "time:$time\n";    
print "time array: " . join (":", (@time)) . "\n";

my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
use Time::Local;
my $btime = timelocal(0,0,0,$mday,$mon,$year);
my $etime = timelocal(59,59,23,$mday,$mon,$year);
print "btime:$btime " . localtime($btime) . " etime:$etime " . localtime($etime) . "\n";
print "year:$year\n";

time:Mon Aug  8 11:40:33 2016
time array: 33:40:11:8:7:116:1:220:1
btime:1470610800 Mon Aug  8 00:00:00 2016 etime:1470697199 Mon Aug  8 23:59:59 2016
year:116
  1. Check file timestamp is between the midnight times. Check all the stuffs.
if (($ts >= $btime) && ($ts <= $etime)) {
   print "File time $ts (".localtime($ts).") is TODAY.\n";
} else {
   print "File time $ts (".localtime($ts).") is NOT today.\n";
   if ($ts < $btime) {
       print "File is BEFORE today. $ts < $btime\n";
   } elsif ($ts > $etime) {
       print "File is in FUTURE. $ts > $etime\n";
   } else {
       print "KERBOOM.\n"
   }
}
Community
  • 1
  • 1
gaoithe
  • 4,218
  • 3
  • 30
  • 38
  • "localtime returns array or integer (ctime) depending on context" - I think you mean "string", not "integer". `localtime` never returns a (single) integer. – Dave Cross Aug 08 '16 at 11:04
  • oops! yes. Thank you. I didn't think properly about that! – gaoithe Aug 08 '16 at 11:21
0

One of the ways how to do it condensed to a one-liner: perl -e '$f = shift; printf "file %s updated at %s\n", $f, scalar localtime((stat $f)[9])' file.

jreisinger
  • 1,493
  • 1
  • 10
  • 21
  • 1
    Shortening slightly - `perl -E'say "file $ARGV[0] updated at " . localtime((stat $ARGV[0])[9])' file` :-) – Dave Cross Aug 08 '16 at 12:08