$a = "Sat Aug 04 23:59:59 GMT 2012"
How to find t开发者_开发知识库hat is that $a
is 100 days older ?
I can't use any extra perl modules because i cant install it on all hosts
You should use DateTime
if available, but if not, then the below should do. Really,
at this stage, you should rolling your own date logic, but it still is pretty easy using 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 )) {
...
}
First you have to parse that string in a DateTime
object, using DateTime::Format::Builder, to build a custom string parser. Then you can get the difference between the two with:
$dt->delta_days( $datetime );
Where $dt is the DateTime
object from string parse, and $datetime is your reference ( another DateTime
object ).
If you get over your fear of modules, Date::Calc would make short work of this:
$ 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
There are a lot of date time modules available in the standard Perl installation which means there's no need to install anything. This module has been available in some form since version Perl 3.x:
- Time::Local
Here are others in version 5.8:
- Time::tm
- Time::gmtime
- Time::localtime
Newer versions of Perl include:
- Time::Piece
You can use the perldoc
command to see which modules you have installed:
C:> perldoc -l Time::Piece
C:\Perl\lib\Time\Piece.pm
Unix stores time in the number of seconds since "The Epoc" which is January 1, 1970, and Perl does the same thing (even on Windows).
Thus, once you translate your date into a Perl time, you can simply subtract 8,640,000 which is the number of seconds in a 100 days. (100 days * 24 Hours/day * 60 minutes/hour * 60 seconds/minute), then convert this back into a string.
At a very, very basic level, you can do this using the gmtime function in Perl and the timegm in the Local::Time module.
Other modules make it very simple to convert time from format to another and even do some math. My favorite is Time::Piece
which allows you to use strptime format to quickly convert your time from whatever format it happens to be in. Then you can use the epoc
member function to convert the time back into seconds, subtract 8,640,000, and reconvert it back into a string.
If Time::Piece is core in your version of 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";
精彩评论