【问题标题】:Subtract days from today date and compare after从今天日期减去天数并在之后进行比较
【发布时间】:2019-07-15 12:45:54
【问题描述】:

以下情况。

我有一个名为2018_12_03_FileName.log 的文件。现在我从文件 (2018_12_03) 中获取日期。

我想将字符串转换为DateTime 对象,这也可以。

$chars =~s/_//g;
$chars = Time::Piece->strptime("$chars", "%Y%m%d");
$chars = $chars->strftime("%d/%m/%Y");

输出

03/12/2018

之后我想得到今天的日期 - 14 天。但这是我的两个问题之一。我尝试了很多方法,但找不到任何适合我的真正解决方案。

my $day14 = DateTime->now();
$day14 -= (2 * ONE_WEEK);

错误:

无法从 DateTime 对象中减去 1209600 (DateTime=HASH(0x6f2d84))。只能从 DateTime 对象中减去 DateTime::Duration 或 DateTime 对象。

现在第二个问题是,我想比较这两个日期,看看文件日期是否在范围内。

my $cmp = DateTime->compare($chars, $day14);

错误:

参数“15/07/2019”在数字 eq (==) 中不是数字

DateTime 对象只能与另一个 DateTime 对象(03/12/2018、15/07/2019)进行比较。

那么如何从今天的日期中减去 14 天,以及之后如何比较这两个日期?

【问题讨论】:

    标签: perl datetime


    【解决方案1】:

    您有点混淆了两个不能很好地协同工作的日期/时间生态系统。

    您可以使用 Time::Piece 和 Time::Seconds 来做到这一点。

    use feature 'say';
    use Time::Piece;
    use Time::Seconds;
    
    my $chars = '2018_12_03';
    
    my $tp = Time::Piece->strptime($chars, '%Y_%m_%d');
    
    my $date14 = $tp - (2 * ONE_WEEK);
    
    say $tp->strftime('%d/%m/%Y');
    say $date14->strftime('%d/%m/%Y');
    

    输出:

    03/12/2018
    19/11/2018
    

    或者您可以使用 DateTime 和朋友来完成。

    use feature 'say';
    use DateTime;
    use DateTime::Format::Strptime;
    
    my $date_parser = DateTime::Format::Strptime->new(
      pattern => '%Y_%m_%d',
      on_error => 'croak',
    );
    
    my $chars = '2018_12_03';
    
    my $dt = $date_parser->parse_datetime($chars);
    
    my $date14 = $dt->clone->subtract( weeks => 2 );
    
    say $dt->strftime('%d/%m/%Y');
    say $date14->strftime('%d/%m/%Y');
    

    输出:

    03/12/2018
    19/11/2018
    

    至于您的最后一个问题,您可以使用标准 Perl 比较运算符(<==>= 等)比较 Time::Piece 对象或 DateTime 对象。但是你必须比较两个相同类型的对象。

    【讨论】:

    • 我认为它是朝那个方向发展的。谢谢!
    • 但是当我使用 clone 时,它​​给了我这个异常:“Can't call method "clone" on an undefined value at ..."
    • @ikegami:是的。比较同一时间的对象不会那么有用:-)
    • @poisn,如果您想要一个异常并在错误输入时出现可能有用的错误消息,而不是只返回undef,则将on_error => 'croak' 添加到传递给DateTime::Format::Strptime->new 的选项列表中。
    • 我已将on_error => 'croak' 添加到构造函数调用中。
    【解决方案2】:

    只是另一种选择,Time::Moment 使日期数学变得非常简单:

    use strict;
    use warnings;
    use Time::Moment;
    
    my $chars = Time::Moment->from_object(Time::Piece->strptime("$chars", "%Y%m%d"));
    my $day14 = Time::Moment->now_utc->minus_days(14)->at_midnight;
    print $day14->strftime('%d/%m/%Y');
    

    这些对象可以与普通运算符进行比较,例如 DateTime 和 Time::Piece。请记住,由于您只关心一天而不是一天中的时间,因此所有数学都应该根据同一时区进行,其中最简单的当然是 UTC。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多