$a = "Sat Aug 04 23:59:59 GMT 2012"
Как узнать, что $a
старше на 100 дней?
Я не могу использовать дополнительные модули Perl, потому что не могу установить их на все хосты.
$a = "Sat Aug 04 23:59:59 GMT 2012"
Как узнать, что $a
старше на 100 дней?
Я не могу использовать дополнительные модули Perl, потому что не могу установить их на все хосты.
Вы должны использовать 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 )) {
...
}
Сначала вам нужно проанализировать эту строку в объекте DateTime
, используя DateTime::Format:: Builder для создания пользовательского синтаксического анализатора строк. Затем вы можете получить разницу между ними с помощью:
$dt->delta_days( $datetime );
Где $dt — это объект DateTime
из синтаксического анализа строки, а $datetime — ваша ссылка (другой объект DateTime
).
from_epoch
для создания объекта DateTime. .
- person oylenshpeegul; 27.09.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
В стандартной установке 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 и снова преобразовать его в строку.
Если 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";