使用 "DateTime" 修改文件后经过的时间错误

Error in elapsed time since modification of file using "DateTime"

我正在尝试清理一个相当大的文件系统。我用stat函数获取每个文件的修改时间

根据perldoc -f stat,返回列表的第十个元素是自纪元以来的最后修改时间(以秒为单位)。

我用DateTime->from_epoch减去DateTime->now算出fule的年龄

    #!/usr/bin/perl

    use strict;
    use warnings;

    use DateTime;

    my $now = DateTime->now();
    #my $now = DateTime->now( time_zone => "America/New_York" );

    $self->{dir} = '/tmp/test';
    opendir(DIR, $self->{dir}) or die $@;
    my @files = grep(/\.txt$/, readdir(DIR));
    closedir(DIR);

    for ( @files ) {

            my $file = stat($self->{dir} . '/' . $_);
            my $mtime = DateTime->from_epoch(epoch => $file->mtime);
            #my $mtime = DateTime->from_epoch(epoch => $file->mtime, time_zone=> "America/New_York");
            my $elapsed = $now - $mtime;
            push(@{$self->{stale}}, {file => $self->{dir} . '/' . $_, mtime => $elapsed->in_units('minutes')}) if $elapsed->in_units('minutes') > 15;
            push(@{$self->{remove}}, {file => $self->{dir} . '/' . $_, mtime => $elapsed->in_units('days')}) if $elapsed->in_units('days') > 10;
    }

如果我手动创建测试文件并更改修改时间,结果会延迟30天

$ touch /tmp/test/test{100..104}.txt -d '-45 days'
$ perl MTIME.pm 
$VAR1 = {
          'mtime' => 15,
          'file' => '/tmp/test/test100.txt'
        }; $VAR1 = {
          'mtime' => 15,
          'file' => '/tmp/test/test104.txt'
        }; $VAR1 = {
          'mtime' => 15,
          'file' => '/tmp/test/test103.txt'
        }; $VAR1 = {
          'mtime' => 15,
          'file' => '/tmp/test/test101.txt'
        }; $VAR1 = {
          'mtime' => 15,
          'file' => '/tmp/test/test102.txt'
        };

我已经尝试 DateTime 个对象,无论是否设置时区,结果都没有差异。

$ touch /tmp/test/test{100..104}.txt -d '-45 days'
$ touch /tmp/test/test{105..110}.txt
$ ll /tmp/test
total 11
-rw-r--r-- 1 root root    0 Apr  3 19:31 test100.txt
-rw-r--r-- 1 root root    0 Apr  3 19:31 test101.txt
-rw-r--r-- 1 root root    0 Apr  3 19:31 test102.txt
-rw-r--r-- 1 root root    0 Apr  3 19:31 test103.txt
-rw-r--r-- 1 root root    0 Apr  3 19:31 test104.txt
-rw-r--r-- 1 root root    0 May 18 19:30 test105.txt
-rw-r--r-- 1 root root    0 May 18 19:30 test106.txt
-rw-r--r-- 1 root root    0 May 18 19:30 test107.txt
-rw-r--r-- 1 root root    0 May 18 19:30 test108.txt
-rw-r--r-- 1 root root    0 May 18 19:30 test109.txt
-rw-r--r-- 1 root root    0 May 18 19:30 test110.txt

工作解决方案:

#!/usr/bin/perl

use strict;
use warnings 'all';

use Data::Dumper;

my $self = bless { }, 'My::Class';

my @files = glob '/tmp/test/*.txt';

for (@files) {
        my $days = int(-M $_);
        my $mins = int((time - (stat $_)[9]) / 60);
        my $item = {
                file  => $_,
                days => $days,
                minutes => $mins
        };
        push @{ $self->{remove} }, $item if $days > 10;
        push @{ $self->{stale} },  $item if $mins > 15;
}

print Dumper $self;

除了任何其他可能的问题:

my $elapsed = $now - $mtime;
push(@{$self->{remove}}, {
    file => $self->{dir} . '/' . $_, 
    mtime => $elapsed->in_units('days')
}) 
if $elapsed->in_units('days') > 10;

没有达到您的预期。

您可以创建一个 10 天的 DateTime::Duration 对象并与之进行比较。为此,您需要一个基准日期时间。

例如

my $base = DateTime->now;
my $ten_days = DateTime::Duration->new( days => 10 );

if ( DateTime::Duration->compare($elapsed,$ten_days,$base) == 1 ){
    push(@{$self->{remove}}, {
        file => $self->{dir} . '/' . $_, 
        mtime => $elapsed->in_units('days')
    }) 
}

不过,我建议,简单地计算 10 天的秒数,看看经过的时间是否比这更长,因为这似乎更容易,而且无论如何都要统计 returns 纪元。

您的问题很难理解,因为您正在编写一个面向对象的模块,然后 运行将其作为程序运行。您显示的代码无法编译,主要是因为 $self 从未声明或定义。如果您希望得到有用的答案,那么请 post 一个完整的程序,我们可以 运行 演示您所问的问题

我无法尝试您的程序并亲自查看问题,但有两个明显的改进需要进行

  • 调用 glob 比打开和读取目​​录、删除不需要的文件并重建每个文件的路径要容易得多添加回目录

  • 您可以使用内置的 -M 运算符以浮点天数发现文件的年龄

我写了这个,它在 class My::Class 中创建一个空对象并向其中添加数据。它包括我已经讨论过的想法,但就像您自己的代码不提供任何输出一样。希望您能理解如何将其解释为您自己的结构

您可能遇到的唯一问题是 mtime 字段是浮点天数。您可能想要应用 intPOSIX::ceil,具体取决于这些值的用途

use strict;
use warnings 'all';

my $self = bless { }, 'My::Class';

my @files = glob '/temp/text/*.txt';

for my $file ( @files ) {

    my $age = -M $file;

    if ( $age >= 10.0 ) {

        my $item = {
            file  => $file,
            mtime => $age,
        };

        push @{ $self->{remove} }, $item;

        push @{ $self->{stale} },  $item if $age >= 15.0;
    }
}