Perl:提取时间戳的开始和结束日期

mrJ*_*rJa 0 perl text timestamp

需要帮助来提取下面的日期和时间戳列表中的日期开始和结束,
假设我从日志文件中提取了以下时间戳数据,并且只需要提取每个日期和时间的开始和结束。输出将用于计算开始到结束之间的时间差。

数据
2021年10月11日 16:27:39
2021年10月11日 16:28:10
2021年10月11日 16:30:47
2021年10月11日 16:30:47
2021年10月12日 09:27: 03
2021年10月12日 10:27:03
2021年10月12日 18:22:15
2021年10月13日 08:57:16
2021年10月13日 08:57:37
2021年10月13日 11:33: 25
2021 年 10 月 13 日 11:33:25
2021 年 11 月 8 日 16:45:17
2021 年 11 月 8 日 16:49:10
2021 年 11 月 8 日 17:00:50
2021 年 11 月 8 日 22:10: 24
2021 年 11 月 9 日 11:51:35
2021 年 11 月 09 日 11:52:40 2021 年 11 月
9 日 12:14:39
2021 年 11 月 9 日 14:23:10
......


预期输出
开始:2021年10月11日16:27:39
结束:2021年10月11日16:30:47
开始:2021年10月12日09:27:03
结束:2021年10月12日18:22:15
开始:2021 年 10 月 13 日 08:57:16
结束:2021 年 10 月 13 日 11:33:25
开始:2021 年 11 月 8 日 16:45:17
结束:2021 年 11 月 8 日 22:10:24
开始: 2021 年 11 月 9 日 11:51:35
结束 :2021 年 11 月 9 日 14:23:10


下面是我的脚本,但我只提取了开始数据

%key;
     while ( <IN> ) {
              $_=~ s/^\s+|\s+$//g; 
              my ($saved_date, $record_date);
              chomp ;
              my ($k, $d) = split;
               
                if (! exists $key{ $k } ) {
                    $key{ $k } = $d;
                    my ($dtformat) = $d =$dtformat;
                    $end_date = Time::Piece->strptime($_, $dtformat);
                    next;
                    
                    my ($dtformat) = $key{ $k } = $dtformat;
                    $saved_date = Time::Piece->strptime($_, $dtformat);
    
                    my ($dtformat) = $d =$dtformat;
                    $record_date = Time::Piece->strptime($_, $dtformat);
                    
                    if ( $record_date - $saved_date > 0 ) {
                       $key{ $k } = $d;
                    }
                }   
        }#endofwhile
        for ( sort keys %key ) {
             print "begin: ", $_, " ",$key{ $_ },"\n"; 

        }
     
Run Code Online (Sandbox Code Playgroud)

输出
开始:2021年11月8日16:45:17
开始:2021年11月9日11:51:35
开始:2021年10月10日21:59:39
开始:2021年10月11日00:21:46
开始:2021年10月12日09:27:03
开始:2021年10月13日08:57:16
开始:2021年9月30日00:21:23

需要帮助如何获得“结束”部分

谢谢

Dav*_*oss 5

秘密在于您用来存储数据的数据结构。由于您对一天的第一个和最后一个时间戳感兴趣,我构建了一个以日期为键的哈希值,其中值是包含当天所有时间戳的数组。然后,我们可以对每天的时间戳进行排序,并轻松提取最早和最新的时间戳。

#!/usr/bin/perl

use strict;
use warnings;

use feature 'say';

use Time::Piece;

# The hash where we'll store our data
my %dates;
# The format of our dates
my $date_format = '%Y-%b-%d %H:%M:%S';

# Read each data item from DATA (or wherever)
while (<DATA>) {
  # Remove the newline
  chomp;

  # Parse the string into a Time::Piece object
  my $date = Time::Piece->strptime($_, $date_format);

  # Store the object in our hash of arrays
  push @{$dates{$date->ymd}}, $date;
}

# Get the list of hash keys sorted by date.
for (sort keys %dates) {
  # For each date key...
  # Get the sorted list of dates into an array...
  my @times = sort { $a->hms cmp $b->hms } @{ $dates{$_} };

  # And print the first and last elements of the array,
  # using the correct format string.
  say "begin: ", $times[0]->strftime($date_format);
  say "end: ", $times[-1]->strftime($date_format);
}

__DATA__
2021-Oct-11 16:27:39
2021-Oct-11 16:28:10
2021-Oct-11 16:30:47
2021-Oct-11 16:30:47
2021-Oct-12 09:27:03
2021-Oct-12 10:27:03
2021-Oct-12 18:22:15
2021-Oct-13 08:57:16
2021-Oct-13 08:57:37
2021-Oct-13 11:33:25
2021-Oct-13 11:33:25
2021-Nov-08 16:45:17
2021-Nov-08 16:49:10
2021-Nov-08 17:00:50
2021-Nov-08 22:10:24
2021-Nov-09 11:51:35
2021-Nov-09 11:52:40
2021-Nov-09 12:14:39
2021-Nov-09 14:23:10
Run Code Online (Sandbox Code Playgroud)