计算数据范围的重叠不是小事,特别是在处理日期/时间值时。我建议Time::Piece::Range
模块。它扩展了核心Time::Piece
模块以处理日期范围,并有一个overlap
方法。
下面的代码实现的功能range_from_file
,当与一个文件的名称提供,读出由含有一种,并创建Time::Piece
对象数组的所有记录的日期。数组被排序,并且Time::Piece::Range
对象由排序列表的第一个和最后一个元素组成并返回。
在两个数据文件上调用此子例程会产生两个Time::Piece::Range
对象,最后调用overlap
方法确定这两个文件是否包含重复的日期/时间。
当应用于您的示例文件data1.txt
和data2.txt
此代码确认它们重叠。
注意,虽然Time::Piece
现在是一个核心模块,Time::Piece::Range
没有了,它也需要非核心模块要安装Date::Range
和Date::Simple
。 cpan
实用程序将自动为您安装依赖关系,但如果您无权扩充Perl安装,则可能会出现问题。
use strict;
use warnings;
use Time::Piece::Range;
sub range_from_file {
my $file = shift;
open my $fh, '<', $file or die qq(Unable to open "$file" for reading);
my @dates;
while (<$fh>) {
next unless /(\d+\.\d+\.\d+[ ]\d+:\d+)/;
push @dates, Time::Piece->strptime($1, '%Y.%m.%d %H:%M');
}
return Time::Piece::Range->new((sort {$a <=> $b} @dates)[0,-1]);
}
my $r1 = range_from_file('data1.txt');
my $r2 = range_from_file('data2.txt');
print $r1->overlaps($r2) ? 'overlap' : 'distinct';
更新
既然你不能使用任何东西,但核心模块,并且您假设strftime
格式包含什么,但固定长度字段(如%B
)我建议这个选择。
我修改了range_from_file
以采取额外的$format
参数,这是strftime
格式用于解码数据。
每个记录的初始日期/时间字段的长度通过使用提供的格式格式化当前日期/时间并查找结果字符串的长度来确定。
从每个文件记录的起始处提取等效字符数,并且该文件中的第一个和最后一个日期存储在数组@dates
中。
将这两个日期转换为Time::Piece
对象,并将其作为范围作为匿名数组返回。
新的子程序overlap
检查两个范围是否重叠。如果第一个的结束落在第二个的开始之前,或者在第一个开始之前的第二个结束之前,则它们是分开的。否则它们重叠。
此代码再次证实您的data1.txt
和data2.txt
文件中的示例数据重叠。
use strict;
use warnings;
use Time::Piece 'localtime';
sub range_from_file {
my ($file, $format) = @_;
open my $fh, '<', $file or die qq(Unable to open "$file" for reading);
my $size = length Time::Piece->new->strftime($format);
my @dates;
while (<$fh>) {
pop @dates if @dates >= 2;
push @dates, substr $_, 0, $size;
}
my @range = map Time::Piece->strptime($_, $format), @dates;
return \@range;
}
sub overlap {
my ($r1, $r2) = @_;
return not $r1->[1] < $r2->[0] or $r2->[1] < $r1->[0];
}
my $r1 = range_from_file('data1.txt', '%Y.%m.%d %H:%M');
my $r2 = range_from_file('data2.txt', '%Y.%m.%d %H:%M');
print overlap($r1, $r2) ? 'overlap' : 'distinct';
我已经尝试用Perl时间:: Piece-> strptime,但只筛选有效的日期格式 – Rob
这是很不明朗,从你的数据是什么构成了*间隔*。你是否需要检查一组间隔中是否有间隙,或只是没有重叠? – Borodin
每个文件内的数据都是连续的。像一个文件是一个区间 文件中的第一个日期是区间和左边的最后一个日期是区间的右侧 – Rob