我有2个带有以下时间戳的变量,并希望得到它们之间的区别
my $startdate = "2015/01/13 13:57:02.079-05:00";
my $enddate ="2015/01/13 13:59:02.079-05:00";
如何实现时差?
答案 0 :(得分:1)
使用DateTime,它只是
$edt->subtract_datetime_absolute($sdt)->in_units('nanoseconds') / 1e9
剩下的就是生成DateTime对象。为此,DateTime :: Format :: Strptime几乎是完美的。
use DateTime::Format::Strptime qw( );
my $sts = "2015/01/13 13:57:02.079-05:00";
my $ets = "2015/01/13 13:59:02.079-05:00";
my $format = DateTime::Format::Strptime->new(
pattern => '%Y/%m/%d %H:%M:%S.%3N%z',
on_error => 'croak',
);
my $sdt = $format->parse_datetime( $sts =~ s/:(?=\d\d\z)//r );
my $edt = $format->parse_datetime( $ets =~ s/:(?=\d\d\z)//r );
my $diff = $edt->subtract_datetime_absolute($sdt)->in_units('nanoseconds') / 1e9;
printf("%.3f\n", $diff); # 120.000
如果您希望代码也在早于5.14的Perl版本上运行,请替换
my $sdt = $format->parse_datetime( $sts =~ s/:(?=\d\d\z)//r );
my $edt = $format->parse_datetime( $ets =~ s/:(?=\d\d\z)//r );
与
s/:(?=\d\d\z)// for $sts, $ets;
my $sdt = $format->parse_datetime($sts);
my $edt = $format->parse_datetime($ets);
答案 1 :(得分:-1)
使用Time::Piece中的strptime()
将您的两个日期解析为对象。从另一个中减去一个Time :: Piece对象,它将为您提供一个Time::Seconds对象。
我不会只是给你代码,因为你需要自己付出一点努力。
答案 2 :(得分:-2)
use strict;
use warnings;
use 5.016;
use Data::Dumper;
use DateTime::Format::Strptime;
my @lines = (
"2015/01/13 13:54:01.853-05:00 11860 acuser *replica_sync_cmd 7f1f9bfff700 10.101.17.111",
"2015/01/13 13:59:01.854-05:00 11860 acuser replica_sync_cmd 7f1f9bfff700 10.101.17.111",
"2015/01/13 13:55:01.266-05:00 11861 acuser *replica_fetch_cmd 7f1f9bfff700 10.101.17.111",
"2015/01/13 13:58:01.267-05:00 11861 acuser replica_fetch_cmd 7f1f9bfff700 10.101.17.111",
);
my %results;
#Group the start and end times together:
for my $line (@lines) {
my ($date, $time, $id, $user, $cmd) = split " ", $line; #splits on any sequence of contiguous whitespace
if ($cmd =~ s/\A [*]//xms) { #if replaced a '*' at beginning of cmd, then...
$results{$id} = ["$date $time", $user, $cmd];
}
else {
unshift @{$results{$id}}, "$date $time"; #push the datetime onto the front of the array
}
}
say Dumper(\%results);
#Subtract the times within each array:
for my $id (keys %results) {
my $end_str = $results{$id}->[0];
$end_str =~ s/:(\d{2})\z/$1/xms; #replace ':' in timezone
my $start_str = $results{$id}->[1];
$start_str =~ s/:(\d{2})\z/$1/xms; #replace ':' in timezone
#"2015/01/13 13:54:01.853-0500"
my $strp = DateTime::Format::Strptime->new(
pattern => "%Y/%m/%d %H:%M:%S.%3N%z",
on_error => 'croak',
);
my $end_dt = $strp->parse_datetime($end_str);
my $start_dt = $strp->parse_datetime($start_str);
#say ref($end_dt); #=>DateTime
#Do datetime math in the same timezone:
$end_dt->set_time_zone('UTC');
$start_dt->set_time_zone('UTC');
my $dur = $end_dt->subtract_datetime_absolute($start_dt);
say Dumper($dur);
say $dur->seconds; #If you care about nano seconds, you'll have to access
#the nanoseconds in $dur and do some math
}
--output:--
$VAR1 = {
'11861' => [
'2015/01/13 13:58:01.267-05:00',
'2015/01/13 13:55:01.266-05:00',
'acuser',
'replica_fetch_cmd'
],
'11860' => [
'2015/01/13 13:59:01.854-05:00',
'2015/01/13 13:54:01.853-05:00',
'acuser',
'replica_sync_cmd'
]
};
$VAR1 = bless( {
'seconds' => 180,
'minutes' => 0,
'end_of_month' => 'wrap',
'nanoseconds' => 1000000,
'days' => 0,
'months' => 0
}, 'DateTime::Duration' );
180
$VAR1 = bless( {
'seconds' => 300,
'minutes' => 0,
'end_of_month' => 'wrap',
'nanoseconds' => 1000000,
'days' => 0,
'months' => 0
}, 'DateTime::Duration' );
300
全球匹配
...
修饰符// g代表全局匹配,并允许匹配运算符在字符串中尽可能多地匹配。在标量上下文中,对字符串的连续调用将使//从匹配跳转到匹配,跟踪字符串中的位置。
...
在列表上下文中,// g返回匹配分组的列表,或者如果没有分组,则返回整个正则表达式的匹配列表。
http://perldoc.perl.org/perlretut.html#Using-regular-expressions-in-Perl
另见:
日期时间::格式:: Strptime
http://search.cpan.org/~drolsky/DateTime-1.18/lib/DateTime.pm#Math_Methods
日期时间
http://search.cpan.org/~drolsky/DateTime-1.18/lib/DateTime.pm#Math_Methods
答案 3 :(得分:-3)
endend一个例子,有点伪代码...不能按原样工作,而是提出这个想法:
#!/usr/bin/perl
use strict;
use warnings;
use Time::Local;
use DateTime::Format::DateParse;
my $startdate = "2015/01/13 13:57:02.079-05:00";
my $enddate ="2015/01/13 13:59:02.079-05:00";
# PArse into components
my $starttime = DateTime::Format::DateParse->parse_datetime( $startdate );
my $endtime = DateTime::Format::DateParse->parse_datetime( $enddate );
# Convert to epoch time
my $st = timelocal($ssec,$smin,$shours,$sday,$smonth, $syear);
my $et = timelocal($esec,$emin,$ehours,$eday,$emonth, $eyear);
#Do the math
my $diff = $et - $s;
print "Difference is $diff seconds...\n";
希望它有所帮助!!