我搞不懂为什么这会给我“无效的日期格式: 2021-09-10”,这是我的代码:
use DateTime;
use DateTime::Span;
use Datetime::Format::ISO8601;
open(FH_Comp, "<", "C:\\Perl_Scripts\\Stock_List_COMPARE.txt") or die("Cannot open Stock_List_COMPARE.txt: $!\n");
my @lines = <FH_Comp>;
close(FH_Comp);
open(FH_CompRev, "<", "C:\\Perl_Scripts\\Stock_List_Rev.txt") or die("Cannot open Stock_List_Rev.txt: $!\n");
my @compRev = <FH_CompRev>;
close(FH_CompRev);
my $iso8601 = DateTime::Format::ISO8601->new;
foreach $lines (@lines) {
@COMPlist = split(",",$lines);
foreach $compRev (@compRev) {
@REVlist = split(",",$compRev);
my $dt_set = DateTime::Span->from_datetimes(
start => $iso8601->parse_datetime($REVlist[0]),
before => $iso8601->parse_datetime($REVlist[4]),
);
if ( $dt_set->contains( $iso8601->parse_datetime($COMPlist[0]) ) ) {
print "Within date range\n";
$Total1 = $COMPlist[2] + $REVlist[2];
print "ADJ Date is '$COMPlist[0]' => $COMPlist[2] + $REVlist[2] = " . $Total1 . " ! '$REVlist[0]' or '$REVlist[4]'";
}
else {
print "Not within date range\n";
}
}
}下面是Stock_List_COMPARE.txt的样子:
2016-06-30, 00354 , 1.00000, 38.62000
2016-06-30, 00354 , 24.00000, 38.62000下面是Stock_List_Rev.txt的外观:
2021-09-10, 00354 , 1.00000, 44.44000, 2021-09-10
2021-08-27, 00354 , 2.00000, 44.24000, 2021-09-10奇怪的是,如果它是硬编码的,而不是从我的文件中获得它,为什么它还能工作(参见下面的代码):
use DateTime;
use DateTime::Span;
use Datetime::Format::ISO8601;
my $iso8601t = DateTime::Format::ISO8601->new;
my $first = "2020-12-10";
my $last = "2021-09-10";
#chomp $last;
my $dt_set = DateTime::Span->from_datetimes(
start => $iso8601t->parse_datetime($first),
before => $iso8601t->parse_datetime($last),
);
if ( $dt_set->contains( $iso8601t->parse_datetime("2021-04-10") ) ) {
print "Within date range\n";
}
else {
print "Not within date range\n";
} 提前感谢!
发布于 2021-09-17 09:41:47
请看更正后的代码,OP的问题是日期没有经过清理,并且包含空格和新行。
函数split采用非常灵活的正则表达式形式的分隔符,这在这种情况下非常有用
注意:
use strict;和use warnings;开始代码,否则一些不受欢迎的行为可能会在中出现
my $variable;声明了一些变量,但其他变量没有声明--在代码中的某个地方,他/她很可能会在局部作用域中重新定义一个变量,这会导致意外行为use strict;
use warnings;
use DateTime;
use DateTime::Span;
use Datetime::Format::ISO8601;
my $fn_compare = 'C:\Perl_Scripts\Stock_List_COMPARE.txt';
my $fn_rev = 'C:\Perl_Scripts\Stock_List_Rev.txt';
open(FH_Comp, "<", $fn_compare) or die("Cannot open $fn_compare: $!");
my @lines = <FH_Comp>;
close(FH_Comp);
open(FH_CompRev, "<", $fn_rev) or die("Cannot open $fn_rev: $!");
my @compRev = <FH_CompRev>;
close(FH_CompRev);
my $iso8601 = DateTime::Format::ISO8601->new;
foreach my $line (@lines) {
my @COMPlist = split('[,\s]+',$line);
foreach my $compRev (@compRev) {
my @REVlist = split('[,\s]+',$compRev);
my $dt_set = DateTime::Span->from_datetimes(
start => $iso8601->parse_datetime($REVlist[0]),
before => $iso8601->parse_datetime($REVlist[4]),
);
if ( $dt_set->contains( $iso8601->parse_datetime($COMPlist[0]) ) ) {
print "Within date range\n";
my $Total1 = $COMPlist[2] + $REVlist[2];
print "ADJ Date is '$COMPlist[0]' => $COMPlist[2] + $REVlist[2] = " . $Total1 . " ! '$REVlist[0]' or '$REVlist[4]'";
}
else {
print "Not within date range\n";
}
}
}输出
Not within date range
Not within date range
Not within date range
Not within date range注意:也许OP可以使用my($var_1,$var_2,$var_3,$var_4) = split('[,\s]+',$line);来分配更有意义的变量名,以使代码更具可读性和更易于维护
注意:请查看以下代码样式是否对您有意义
if ( $dt_set->contains( $iso8601->parse_datetime($COMPlist[0]) ) ) {
print "Within date range\n";
printf "ADJ Date is %s => %s + %s = %s ! %s or %s\n",
$COMPlist[0],
$COMPlist[2],
$REVlist[2],
$COMPlist[2] + $REVlist[2],
$REVlist[0],
$REVlist[4];
} else {
print "Not within date range\n";
} 注意:print "$var\n";可以替换为say $var; --在代码文件的顶部添加use feature 'say';行
参考:say
https://stackoverflow.com/questions/69219962
复制相似问题