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

时间:2017-05-18 23:35:50

标签: perl datetime epoch

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

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

我使用stat并减去DateTime->from_epoch来计算fule的年龄

DateTime->now

如果我手动创建测试文件并更改修改时间,则结果将关闭30天

    #!/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;
    }

我已尝试$ 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

2 个答案:

答案 0 :(得分:0)

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

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天内的秒数,看看过去的时间是否大于此,因为它看起来更容易,而且无论如何stat都会返回时代。

答案 1 :(得分:0)

您的问题很难理解,因为您正在编写面向对象的模块,然后将其作为程序运行。您展示的代码不会编译,主要是因为永远不会声明或定义$self。如果您希望得到有用的答案,那么请发布一个我们可以运行的完整程序,它可以证明您所询问的问题

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

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

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

我写过这个,它在类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;
    }
}