首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >以strftime格式比较日期间隔

以strftime格式比较日期间隔
EN

Stack Overflow用户
提问于 2012-06-12 18:40:06
回答 3查看 810关注 0票数 0

我有多个日期为strftime format的输入文件,.The日期格式是输入变量之一。我需要确定它们的时间线是否连续;换句话说,如果所有输入文件的日期间隔不重叠。

文件中的数据是连续的。这就像一个文件就是一个间隔。文件中的第一个日期位于间隔的左侧,而最后一个日期位于间隔的右侧。

为了更好地演示我的问题(只是一个数据格式为%Y.%m.%d%H:%M的示例):

有2个数据文件,其中日期格式为%Y.%m.%d %H:%M

data1.txt

代码语言:javascript
运行
复制
2012.11.20 17:10 134343
2012.11.21 00:10 13323343
2012.12.22 15:10 13432323

data2.txt

代码语言:javascript
运行
复制
2012.10.20 17:10 134343
2012.11.29 00:10 13333223343
2012.11.30 15:10 134323123

因此,您可以看到data1.txt和data2.txt文件中的日期是重叠的。

代码语言:javascript
运行
复制
       2012.10.20         2012.11.20           2012.11.30                2012.12.22

data2.txt <=============================================>

代码语言:javascript
运行
复制
                   data1.txt <===================================================>

我在bash中实现了这个问题,但我也欢迎一些Perl片段。

我找不到任何简单的解决方案。

谢谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-06-12 20:34:17

计算数据范围的重叠不是一件容易的事情,特别是在处理日期/时间值时。

我建议使用Time::Piece::Range模块。它扩展了核心Time::Piece模块以处理日期范围,并具有overlap方法。

下面的代码实现了一个函数range_from_file,当提供文件名时,该函数从包含日期的所有记录中读取一个日期,并创建一个Time::Piece对象数组。对数组进行排序,并由排序列表的第一个和最后一个元素组成一个Time::Piece::Range对象并返回。

对两个数据文件调用此子例程将生成两个Time::Piece::Range对象,最后调用overlap方法将确定这两个文件是否包含重复的日期/时间。

当应用于样例文件data1.txtdata2.txt时,这段代码确认它们是重叠的。

请注意,尽管Time::Piece现在是核心模块,但Time::Piece::Range不是,它还需要安装非核心模块Date::RangeDate::Simplecpan实用程序将自动为您安装依赖项,但是如果您没有权限扩充您的Perl安装,这可能是一个问题。

代码语言:javascript
运行
复制
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.txtdata2.txt中的样本数据是重叠的。

代码语言:javascript
运行
复制
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';
票数 1
EN

Stack Overflow用户

发布于 2012-06-12 23:59:59

好的,所以你需要比较日期(有没有时间?)已转换为词法上可比较的格式的。这意味着日期始终是YYYY.MM.DD (如果需要,可以使用前导零。

代码语言:javascript
运行
复制
#!/bin/bash
file1=$1
file2=$2
read -r start1 end1 < <(awk 'NR == 1 {print "$1-$2"} END {print "$1-$2"}' "$file1")
read -r start2 end2 < <(awk 'NR == 1 {print "$1-$2"} END {print "$1-$2"}' "$file2")
if [[ $start1 > $start2 || $end1 > $start2 ]]
then
    echo "Overlap!"
fi
票数 0
EN

Stack Overflow用户

发布于 2012-06-12 20:49:14

使用perl就可以了。

如果这两个文件包含只有当file1的最后一行的日期早于file2的第一行时,日期才会重叠。

1)获取第一行2)解析行my ($date1,$data) = line (/\t/,$line);或者你文本:Csv 3)解析date1和date2 my ($Y1,$m1,$d1,$H1,$M1) = $date =~ Csv 4)使用DateTime创建纪元;

$dt1 = DateTime->new( year => $Y1,month => $m1,day => $d1,hour => $h1,minute => $m1,second => 0,纳秒=> 0,time_zone => 'UTC',);my $epoch1 = $dt1->epoch;my $epoch2 = $dt2->epoch;

5)如果epoch1比epoch2小,你就是好的。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10994990

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档