Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 开始日期和结束日期之间的天数列表_Perl_Datetime - Fatal编程技术网

Perl 开始日期和结束日期之间的天数列表

Perl 开始日期和结束日期之间的天数列表,perl,datetime,Perl,Datetime,我试图在Perl中获得开始日期和结束日期之间的每个日期。我最初使用下面的代码做了7天: use Time::ParseDate; my $newdate; my $newtime; my @dates = (); my $newtime->[0] = parsedate($start_datetime); my $newdate->[0] = strftime("%Y-%m-%d",localtime($newtime->[0])); push(@dates, $newd

我试图在Perl中获得开始日期和结束日期之间的每个日期。我最初使用下面的代码做了7天:

use Time::ParseDate;  
my $newdate;
my $newtime;
my @dates = ();

my $newtime->[0] = parsedate($start_datetime);
my $newdate->[0] = strftime("%Y-%m-%d",localtime($newtime->[0]));
push(@dates, $newdate->[0]);
my $newtime->[1] = parsedate($newdate->[0]) + (1 * 24 * 60 * 60);
my $newdate->[1] = strftime("%Y-%m-%d",localtime($newtime->[1]));
push(@dates, $newdate->[1]);
my $newtime->[2] = parsedate($newdate->[1]) + (1 * 24 * 60 * 60);
my $newdate->[2] = strftime("%Y-%m-%d",localtime($newtime->[2]));
push(@dates, $newdate->[2]);
my $newtime->[3] = parsedate($newdate->[2]) + (1 * 24 * 60 * 60);
my $newdate->[3] = strftime("%Y-%m-%d",localtime($newtime->[3]));
push(@dates, $newdate->[3]);
my $newtime->[4] = parsedate($newdate->[3]) + (1 * 24 * 60 * 60);
my $newdate->[4] = strftime("%Y-%m-%d",localtime($newtime->[4]));
push(@dates, $newdate->[4]);
my $newtime->[5] = parsedate($newdate->[4]) + (1 * 24 * 60 * 60);
my $newdate->[5] = strftime("%Y-%m-%d",localtime($newtime->[5]));
push(@dates, $newdate->[5]);
my $newtime->[6] = parsedate($newdate->[5]) + (1 * 24 * 60 * 60);
my $newdate->[6] = strftime("%Y-%m-%d",localtime($newtime->[6]));
push(@dates, $newdate->[6]);
my $newtime->[7] = parsedate($newdate->[6]) + (1 * 24 * 60 * 60);
my $newdate->[7] = strftime("%Y-%m-%d",localtime($newtime->[7]));
push(@dates, $newdate->[7]);
但是意识到它应该可以工作任意天数。 因此,我尝试了下面的循环,但它对我不太起作用

my $newdate;
my $newtime;
my @dates = ();
my $start_date = substr($start_datetime, 0, 10) ; 
$start_date =~ s/-//gi;  
my $end_date = substr($end_datetime, 0, 10) ;
$end_date =~ s/-//gi;

my $days = yyyymmdd_to_rata_die($end_date) - yyyymmdd_to_rata_die($start_date);
my $newtime->[0] = parsedate($xml->{action_content}->{start_date});
my $newdate->[0] = strftime("%Y-%m-%d",localtime($newtime->[0]));
push(@dates, $newdate->[0]);
for(my $x=1;$x<$days;$x++)
{
  my $newtime->[$x] = parsedate($newdate->[$x-1]) + (1 * 24 * 60 * 60);
  my $newdate->[$x] = strftime("%Y-%m-%d",localtime($newtime->[$x]));
  push(@dates, $newdate->[$x]);
}
my$newdate;
我的$newtime;
我的@dates=();
我的$start\u date=substr($start\u datetime,0,10);
$start_date=~s/-//gi;
my$end\u date=substr($end\u datetime,0,10);
$end_date=~s/-//gi;
我的$days=yyyyymmdd_to_rata_die($end_日期)-yyyymmdd_to_rata_die($start_日期);
my$newtime->[0]=parsedate($xml->{action\u content}->{start\u date});
我的$newdate->[0]=strftime(%Y-%m-%d),localtime($newtime->[0]);
推送(@dates,$newdate->[0]);
对于(my$x=1;$x[$x]=parsedate($newdate->[$x-1])+(1*24*60*60);
我的$newdate->[$x]=strftime(%Y-%m-%d),localtime($newtime->[$x]);
推送(@dates,$newdate->[$x]);
}
我从Stackoverflow的一个问题中得到了下面的函数

sub yyyymmdd_to_rata_die
{
    use integer;
    my ( $y, $m, $d ) = $_[0] =~ /\A([0-9]{4})([0-9]{2})([0-9]{2})\z/
    or return;

    my $adj;

    if ( $m <= 2 ) 
    {
        $y -= ( $adj = ( 14 - $m ) / 12 );
        $m += 12 * $adj;
    }
    elsif ( $m > 14 ) 
    {
        $y += ( $adj = ( $m - 3 ) / 12 );
        $m -= 12 * $adj;
    }

    $d += ( $m * 367 - 1094 ) / 12 + $y % 100 * 1461 / 4 + ( $y / 100 * 36524 + $y / 400 ) - 306;
}
将yyyymmdd分为
{
使用整数;
我的($y,$m,$d)=$\[0]=~/\A([0-9]{4})([0-9]{2})([0-9]{2})\z/
或返回;
我的$adj;
如果有的话(14百万美元)
{
$y+=($adj=($m-3)/12);
$m-=12*$adj;
}
$d+=($m*367-1094)/12+$y%100*1461/4+($y/100*36524+$y/400)-306;
}
任何援助都将非常感激

编辑: $start_datetime=“2014-09-01 00:00:00”; $end_datetime=“2014-09-07 23:59:59”

我需要开始日期和结束日期之间的所有天数,即
2014-09-01
2014-09-02
2014-09-03
2014-09-04
2014-09-05
2014-09-06

2014-09-07

通过使用以下工具,你的生活会变得更加轻松:


更新:看起来使用了非常类似的方法,处理您添加到问题中的输入和所需的输出。

您可以通过使用以下内容使您的生活更加轻松:


更新:看起来使用了非常类似的方法,处理您添加到问题中的输入和所需的输出。

我建议您使用该模块。它不需要安装,因为它自Perl 5版本10以来一直是一个核心模块

看起来是这样的

use strict;
use warnings;

use Time::Piece;

print days_between('2014-01-01', '2014-12-01'), "\n";

sub days_between {
  my ($start, $end) = map Time::Piece->strptime($_, '%Y-%m-%d'), @_;
  ($end - $start)->days;
}
use Regexp::Common qw/ time /;

my $date_re = $RE{time}{strftime}{-pat => '%Y-%m-%d'};
sub days_from_to {

   my @limits = map /($date_re)/, @_;

   @limits = map Time::Piece->strptime($_, '%Y-%m-%d'), @limits;

   my @dates = ( $limits[0] );
   push @dates, $dates[-1] + ONE_DAY while $dates[-1] < $limits[-1];   

   map $_->ymd, @dates;
}
输出

334
7 days:
2014-09-01
2014-09-02
2014-09-03
2014-09-04
2014-09-05
2014-09-06
2014-09-07

更新

很抱歉。我误解了您的要求,并认为您需要两个日期之间的天数。此程序打印两个限制之间的所有日期的列表。如果在标量上下文中调用,它将提供列表中的天数,如前所述

use strict;
use warnings;

use Time::Piece;
use Time::Seconds qw/ ONE_DAY /;

printf "%d days:\n", scalar days_from_to('2014-09-01 00:00:00', '2014-09-07 23:59:59');

print "$_\n" for days_from_to('2014-09-01 00:00:00', '2014-09-07 23:59:59');

sub days_from_to {

   my @limits = map /(\d\d\d\d-\d\d-\d\d)/, @_;
   @limits = map Time::Piece->strptime($_, '%Y-%m-%d'), @limits;

   my @dates = ( $limits[0] );
   push @dates, $dates[-1] + ONE_DAY while $dates[-1] < $limits[-1];   

   map $_->ymd, @dates;
}

更新

如果需要一个更关键的正则表达式来拒绝像
0123-45-67
这样的字符串,那么您可以使用这个正则表达式

my $date_re = qr/(?:
   (?: (?:19|20)[0-9][0-9] ) -
   (?:
      (?: 0?[469] | 11 ) -
      (?: 0?[1-9] | [12][0-9] | 30 )
   |
      (?: 0?[13578] | 1[02] ) -
      (?: 0?[1-9] | [12][0-9] | 3[01] )
   |
      (?: 0?2 ) -
      (?: 0?[1-9] | [12][0-9] )
   )
)/x;
它将接受1900年至2099年之间的日期,并确保该月的日期对该月有效。唯一的限制条件是它将允许任何一年的2月29日

或者您可能更喜欢这样使用

use strict;
use warnings;

use Time::Piece;

print days_between('2014-01-01', '2014-12-01'), "\n";

sub days_between {
  my ($start, $end) = map Time::Piece->strptime($_, '%Y-%m-%d'), @_;
  ($end - $start)->days;
}
use Regexp::Common qw/ time /;

my $date_re = $RE{time}{strftime}{-pat => '%Y-%m-%d'};
sub days_from_to {

   my @limits = map /($date_re)/, @_;

   @limits = map Time::Piece->strptime($_, '%Y-%m-%d'), @limits;

   my @dates = ( $limits[0] );
   push @dates, $dates[-1] + ONE_DAY while $dates[-1] < $limits[-1];   

   map $_->ymd, @dates;
}
但这与2月29日的情况相同

子例程如下所示

use strict;
use warnings;

use Time::Piece;

print days_between('2014-01-01', '2014-12-01'), "\n";

sub days_between {
  my ($start, $end) = map Time::Piece->strptime($_, '%Y-%m-%d'), @_;
  ($end - $start)->days;
}
use Regexp::Common qw/ time /;

my $date_re = $RE{time}{strftime}{-pat => '%Y-%m-%d'};
sub days_from_to {

   my @limits = map /($date_re)/, @_;

   @limits = map Time::Piece->strptime($_, '%Y-%m-%d'), @limits;

   my @dates = ( $limits[0] );
   push @dates, $dates[-1] + ONE_DAY while $dates[-1] < $limits[-1];   

   map $_->ymd, @dates;
}
sub-days\u from\u to{
我的@limits=map/($date\u re)/,@;
@限制=映射时间::片段->strTime($389;,,%Y-%m-%d'),@limits;
我的@dates=($limits[0]);
推送@dates、$dates[-1]+一天,而$dates[-1]<$limits[-1];
地图->ymd,日期;
}

我建议您使用该模块。它不需要安装,因为它自Perl 5版本10以来一直是一个核心模块

看起来是这样的

use strict;
use warnings;

use Time::Piece;

print days_between('2014-01-01', '2014-12-01'), "\n";

sub days_between {
  my ($start, $end) = map Time::Piece->strptime($_, '%Y-%m-%d'), @_;
  ($end - $start)->days;
}
use Regexp::Common qw/ time /;

my $date_re = $RE{time}{strftime}{-pat => '%Y-%m-%d'};
sub days_from_to {

   my @limits = map /($date_re)/, @_;

   @limits = map Time::Piece->strptime($_, '%Y-%m-%d'), @limits;

   my @dates = ( $limits[0] );
   push @dates, $dates[-1] + ONE_DAY while $dates[-1] < $limits[-1];   

   map $_->ymd, @dates;
}
输出

334
7 days:
2014-09-01
2014-09-02
2014-09-03
2014-09-04
2014-09-05
2014-09-06
2014-09-07

更新

很抱歉。我误解了您的要求,并认为您需要两个日期之间的天数。此程序打印两个限制之间的所有日期的列表。如果在标量上下文中调用,它将提供列表中的天数,如前所述

use strict;
use warnings;

use Time::Piece;
use Time::Seconds qw/ ONE_DAY /;

printf "%d days:\n", scalar days_from_to('2014-09-01 00:00:00', '2014-09-07 23:59:59');

print "$_\n" for days_from_to('2014-09-01 00:00:00', '2014-09-07 23:59:59');

sub days_from_to {

   my @limits = map /(\d\d\d\d-\d\d-\d\d)/, @_;
   @limits = map Time::Piece->strptime($_, '%Y-%m-%d'), @limits;

   my @dates = ( $limits[0] );
   push @dates, $dates[-1] + ONE_DAY while $dates[-1] < $limits[-1];   

   map $_->ymd, @dates;
}

更新

如果需要一个更关键的正则表达式来拒绝像
0123-45-67
这样的字符串,那么您可以使用这个正则表达式

my $date_re = qr/(?:
   (?: (?:19|20)[0-9][0-9] ) -
   (?:
      (?: 0?[469] | 11 ) -
      (?: 0?[1-9] | [12][0-9] | 30 )
   |
      (?: 0?[13578] | 1[02] ) -
      (?: 0?[1-9] | [12][0-9] | 3[01] )
   |
      (?: 0?2 ) -
      (?: 0?[1-9] | [12][0-9] )
   )
)/x;
它将接受1900年至2099年之间的日期,并确保该月的日期对该月有效。唯一的限制条件是它将允许任何一年的2月29日

或者您可能更喜欢这样使用

use strict;
use warnings;

use Time::Piece;

print days_between('2014-01-01', '2014-12-01'), "\n";

sub days_between {
  my ($start, $end) = map Time::Piece->strptime($_, '%Y-%m-%d'), @_;
  ($end - $start)->days;
}
use Regexp::Common qw/ time /;

my $date_re = $RE{time}{strftime}{-pat => '%Y-%m-%d'};
sub days_from_to {

   my @limits = map /($date_re)/, @_;

   @limits = map Time::Piece->strptime($_, '%Y-%m-%d'), @limits;

   my @dates = ( $limits[0] );
   push @dates, $dates[-1] + ONE_DAY while $dates[-1] < $limits[-1];   

   map $_->ymd, @dates;
}
但这与2月29日的情况相同

子例程如下所示

use strict;
use warnings;

use Time::Piece;

print days_between('2014-01-01', '2014-12-01'), "\n";

sub days_between {
  my ($start, $end) = map Time::Piece->strptime($_, '%Y-%m-%d'), @_;
  ($end - $start)->days;
}
use Regexp::Common qw/ time /;

my $date_re = $RE{time}{strftime}{-pat => '%Y-%m-%d'};
sub days_from_to {

   my @limits = map /($date_re)/, @_;

   @limits = map Time::Piece->strptime($_, '%Y-%m-%d'), @limits;

   my @dates = ( $limits[0] );
   push @dates, $dates[-1] + ONE_DAY while $dates[-1] < $limits[-1];   

   map $_->ymd, @dates;
}
sub-days\u from\u to{
我的@limits=map/($date\u re)/,@;
@限制=映射时间::片段->strTime($389;,,%Y-%m-%d'),@limits;
我的@dates=($limits[0]);
推送@dates、$dates[-1]+一天,而$dates[-1]<$limits[-1];
地图->ymd,日期;
}

请给出一个您需要的输入和相应输出的示例。您的代码表明您正在使用
XML::Simple
。如果您需要,我强烈建议您转移到其他地方,因为使用它绝不简单。请给出一个您需要的输入和相应输出的示例。您的代码您正在使用的EST
XML::Simple
。如果是这样,我强烈建议您转移到其他地方,因为使用它并不简单。看起来参数是开始和结束日期,它们包括时间字段,如
2014-09-07 23:59:59
,因此
strptime
将在字符串w的末尾引发垃圾除非修剪,否则将引发警告。看起来参数是开始日期和结束日期,并且它们包含时间字段,如
2014-09-07 23:59:59
,因此
strptime
将在字符串末尾引发垃圾警告,除非修剪。@ladyT:不客气。请注意,正则表达式将删除除第一个类似的内容之外的所有内容日期。这意味着时间是不必要的,但是你可以传递一整行日志,甚至多行文本,只要其中的第一个日期是你想要的。但是要小心像
0000-99-99
这样的东西,它会完全混淆它!@ladyT:不客气。请注意,正则表达式会删除exc中的所有内容