如何查找当天和输入日期之间的天数差异

时间:2011-09-27 10:55:18

标签: perl shell datediff

$a = "Sat Aug 04 23:59:59 GMT 2012"

如何找到$a比100天大?

我无法使用任何额外的perl模块,因为我无法在所有主机上安装它

5 个答案:

答案 0 :(得分:1)

首先,您必须使用DateTime::Format::BuilderDateTime对象中解析该字符串,以构建自定义字符串解析器。然后你可以通过以下方式获得两者之间的差异:

$dt->delta_days( $datetime );

其中$ dt是字符串解析中的DateTime对象,$ datetime是你的引用(另一个DateTime对象)。

答案 1 :(得分:1)

如果可以,您应该使用DateTime,但如果没有,则应使用以下内容。真, 在这个阶段,你应该滚动自己的日期逻辑,但使用 core 模块POSIX仍然很容易。

use strict;
use warnings;
use POSIX ();

# get a list of month symbols
my @mons = qw/Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec/;

# Create a symbol -> number table
my %num_for 
    = do {
        my $mon = 0;
        map { $_ => $mon++ } @mons;
    };

# Create the alternation of months

# Create line regex
my $time_rex 
    = qr/ (${\join( '|', @mons )}) 
          \s+ 
          0? (\d+) 
          \s+ 
          (\d{2}) : (\d{2}) : (\d{2}) 
          \s+ 
           # I made the tz optional to handle scalar( localtime )
          (?: (\p{alpha}+) \s+ )?
          (\d{4})
        /x
     ;
...

# Convienience function
sub get_time_value {
    # parse date string
    return unless my @fields = ( shift =~ /$time_rex/ );
    # get numerical month
    $fields[0]  = $num_for{ $fields[0] };
    # perl year kludge
    $fields[-1] -= 1900;
    return wantarray ? @fields[ 4, 3, 2, 1, 0, 6, 5 ]
         :             POSIX::mktime( @fields[ 4, 3, 2, 1, 0, 6 ] )
         ;
}

sub days_prior_to_now {
    return unless defined( my $days_prior = shift );
    return time unless $days_prior;

    $days_prior = - $days_prior if $days_prior < 0;
    my $date_string =  scalar( localtime );
    return unless my ( $sec, $min, $hr, $day, $mon, $year, $tz ) 
           = get_time_value( $date_string )
           ;
    return POSIX::mktime( $sec, $min, $hr, $day - $days_prior, $mon, $year );
}

sub is_100_days_before_now {
    my $a_string    = shift;

    croak "Could not parse '$a_string'!" 
        unless my $a_value = get_time_value( $a_string );
    return $a_value < days_prior_to_now( 100 );
}

if ( is_100_days_before_now( $a )) { 
    ...
}

答案 2 :(得分:1)

如果你克服了对模块的恐惧,Date::Calc会做出简短的工作:

$ perl -MDate::Calc=Delta_Days,Parse_Date,Today -E 'say Delta_Days(Today, Parse_Date(shift))' "Sat Aug 04 23:59:59 GMT 2012"
312

答案 3 :(得分:1)

标准Perl安装中有很多日期时间模块,这意味着无需安装任何东西。自Perl 3.x版本以来,该模块已经以某种形式提供:

以下是版本5.8中的其他内容:

较新版本的Perl包括:

您可以使用perldoc命令查看已安装的模块:

C:> perldoc -l Time::Piece
C:\Perl\lib\Time\Piece.pm

Unix存储自1970年1月1日“The Epoc”以来的秒数,而Perl也做同样的事情(即使在Windows上)。

因此,一旦您将日期转换为Perl时间,您可以简单地减去8,640,000,这是100天内的秒数。 (100天* 24小时/天* 60分钟/小时* 60秒/分钟),然后将其转换回字符串。

在非常非常基础的层面上,您可以使用Perl中的gmtime函数和Local :: Time模块中的timegm来完成此操作。

其他模块可以非常简单地将时间从格式转换为另一种模式,甚至可以进行一些数学运算。我最喜欢的是Time::Piece,它允许您使用strptime格式快速转换您所处的格式。然后您可以使用epoc成员函数将时间转换回来到秒,减去8,640,000,然后将其重新转换为字符串。

答案 4 :(得分:0)

如果Time :: Piece是你的perl版本的核心:

use strict;
use warnings;

use Time::Piece;
use Time::Seconds qw(ONE_DAY);

my $t = "Sat Aug 04 23:59:59 GMT 2012";
my $dt = Time::Piece->strptime($t, "%a %b %d %T %Z %Y");

my $day_str = $dt->strftime("%F");
my $day = Time::Piece->strptime($day_str, "%Y-%m-%d") + 100.5*ONE_DAY();

print $day->strftime("%F"),"\n";