Как найти разницу дней между текущим днем ​​и датой ввода - PullRequest
1 голос
/ 27 сентября 2011
$a = "Sat Aug 04 23:59:59 GMT 2012"

Как узнать, что $a старше на 100 дней?

Я не могу использовать дополнительные модули Perl, потому что не могу установить его на всех хостах

Ответы [ 5 ]

1 голос
/ 27 сентября 2011

В стандартной установке Perl доступно много модулей даты и времени, что означает, что вам не нужно ничего устанавливать. Этот модуль был доступен в той или иной форме начиная с версии Perl 3.x:

Вот другие версии 5.8:

Более новые версии Perl включают:

Вы можете использовать команду perldoc, чтобы увидеть, какие модули вы установили:

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

Unix хранит время в секундах, прошедших с «Эпока», то есть 1 января 1970 года, и Perl делает то же самое (даже в Windows).

Таким образом, как только вы переведете свою дату в Perl-время, вы можете просто вычесть 8 640 000, то есть количество секунд в 100 днях. (100 дней * 24 часа / день * 60 минут / час * 60 секунд / минута), затем преобразуйте это обратно в строку.

На очень базовом уровне вы можете сделать это, используя функцию gmtime в Perl и timegm в модуле Local :: Time.

Другие модули позволяют очень просто преобразовывать время из формата в другой и даже выполнять некоторые математические операции. Мой фаворит - Time::Piece, который позволяет вам использовать формат strptime , чтобы быстро конвертировать ваше время из любого формата, в котором он находится. Затем вы можете использовать функцию члена epoc, чтобы конвертировать время обратно в секунды вычтите 8 640 000 и преобразовайте его обратно в строку.

1 голос
/ 27 сентября 2011

Вы должны использовать DateTime, если доступно, но если нет, то следует сделать следующее. В самом деле, на этом этапе вы должны использовать свою собственную логику дат, но все еще довольно просто использовать core module 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 )) { 
    ...
}
1 голос
/ 27 сентября 2011

Если вы преодолеете свой страх перед модулями, 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
1 голос
/ 27 сентября 2011

Сначала вы должны проанализировать эту строку в объекте DateTime, используя DateTime :: Format :: Builder , чтобы создать собственный анализатор строк. Тогда вы можете получить разницу между ними с помощью:

$dt->delta_days( $datetime );

Где $ dt - это DateTime объект из анализа строки, а $ datetime - ваша ссылка (еще один DateTime объект).

0 голосов
/ 28 сентября 2011

Если 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";
...