【问题标题】:Convert Old Unix Date to Perl and compare将旧 Unix 日期转换为 Perl 并进行比较
【发布时间】:2012-02-27 12:28:29
【问题描述】:

要求 - 我的文件名为“Rajesh.1202242219”。数字不过是日期“date '+%y''%m''%d''%H''%M'”格式。 现在我正在尝试编写一个 perl 脚本来从文件名中提取数字并与当前系统日期和时间进行比较,并根据此比较的输出,使用 perl 打印一些值。

方法:

从文件名中提取数字:

if ($file =~ /Rajesh.(\d+).*/) {
print $1;
        }

将此时间转换为 perl 中的可读时间

my $sec  =  0;  # Not Feeded
my $min  =  19;
my $hour =  22;
my $day  =  24;
my $mon  = 02   - 1;
my $year = 2012 - 1900;
my $wday = 0;   # Not Feeded
my $yday = 0;   # Not Feeded

my $unixtime = mktime ($sec, $min, $hour, $day, $mon, $year, $wday, $yday);
print "$unixtime\n";
my $readable_time = localtime($unixtime);
print "$readable_time\n";

查找当前时间并比较...

my $CurrentTime = time();
my $Todaydate = localtime($startTime);

但这里的问题是,我没有得到如何从$1 中提取 2 位数字并分配给$sec$min 等的解决方案。有什么帮助吗?

另外,如果您对此问题陈述有好的方法,请与我分享

【问题讨论】:

    标签: perl shell date time


    【解决方案1】:

    我喜欢使用时间对象来简化逻辑。我在这里使用Time::Piece,因为它简单且重量轻(并且是核心的一部分)。 DateTime 可以是另一种选择。

    use Time::Piece;
    my ( $datetime ) = $file =~ /(\d+)/;
    my $t1 = Time::Piece->strptime( $datetime, '%y%m%d%H%M' );
    my $t2 = localtime(); # equivalent to Time::Piece->new
    
    # you can do date comparisons on the object
    if ($t1 < $t2) {
        # do something
        print "[$t1] < [$t2]\n";
    }
    

    【讨论】:

      【解决方案2】:

      还不如教DateTime::Format::Strptime,让比较更简单:

      use DateTime qw();
      use DateTime::Format::Strptime qw();
      
      if (
          DateTime::Format::Strptime
              ->new(pattern => '%y%m%d%H%M')
              ->parse_datetime('Rajesh.1202242219')
          < DateTime->now
      ) {
          say 'filename timestamp is earlier than now';
      } else {
          say 'filename timestamp is later than now';
      };
      

      【讨论】:

      • 日期时间是一把三刃剑。
      • +1,但是当DateTime::Format::Strptime 已经这样做并使用带有空导入列表的两个模块时,您为什么要明确地use DateTime
      • flesk:两者都与我选择的好风格有关:我不会依赖隐藏效果。每当我使用一个模块时,我都会先明确地加载它。我无法构建一个与此代码相关的示例,而且 DT::F::S 无论如何都不太可能在某天停止加载 DT,但我喜欢保持一致。 – 请参阅empty import list。 ––
      • @daxim 因此,通过使用空列表,您可以阻止模块自动导入变量和函数名称?
      • 类似的东西,是的。同样,对于具体示例并不重要,但 consistency++.
      【解决方案3】:
      my ($year, $month, $day, $hour, $min) = $file =~ /(\d{2})/g;
      
      if ($min) {
          $year += 100; # Assuming 2012 and not 1912
          $month--;
          # Do stuff
      }
      

      【讨论】:

      • $min 可以是“00”,所以如果你说:“if (defined $min){”也许会更容易阅读。猜猜它的工作原理就像现在一样,因为“ 00”是真的吗??
      • 如果defined $min 更具可读性是个人喜好问题,但对于指定的文件名格式,$min 永远不会被定义和错误,因为“00”是真的,不像“0”。
      【解决方案4】:

      我认为unpack 可能更合适。

      if ( my ( $num ) = $file =~ /Rajesh.(\d+).*/ ) {
          my ( $year, $mon, $day, $hour, $min ) = unpack( 'A2 A2 A2 A2 A2', $num ); 
          my $ts = POSIX::mktime( 0, $min, $hour, $day, $mon - 1, $year + 100 );
          ...
      }
      

      【讨论】:

      • 他使用的是两位数的年份。
      • @flesk,是的,看到并修复了它。
      • 一旦我这样做,$ts - $CurrentTime,这将返回不正确的 -$CurrentTime 值。您能否建议您如何比较这个日期和当前日期?
      【解决方案5】:

      使用解析日期的模块可能会很好。此代码将解析日期并返回 DateTime 对象。请参阅documentation 了解操作此对象的多种方法。

      use DateTime::Format::Strptime;
      
      my $date = "1202242219";
      my $dt = get_obj($date);
      
      sub get_obj {
          my $date = shift;
          my $strp = DateTime::Format::Strptime->new(
              pattern     => '%y%m%d%H%M'
          );
          return $strp->parse_datetime($date);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-10-22
        • 2017-11-02
        • 1970-01-01
        • 2018-07-22
        • 1970-01-01
        • 1970-01-01
        • 2017-09-05
        相关资源
        最近更新 更多