首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Perl Datetime::Format::ISO8601问题

Perl Datetime::Format::ISO8601问题
EN

Stack Overflow用户
提问于 2021-09-17 08:11:47
回答 1查看 63关注 0票数 0

我搞不懂为什么这会给我“无效的日期格式: 2021-09-10”,这是我的代码:

代码语言:javascript
复制
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的样子:

代码语言:javascript
复制
2016-06-30, 00354                          , 1.00000, 38.62000
2016-06-30, 00354                          , 24.00000, 38.62000

下面是Stock_List_Rev.txt的外观:

代码语言:javascript
复制
2021-09-10,  00354                         , 1.00000, 44.44000, 2021-09-10
2021-08-27,  00354                         , 2.00000, 44.24000, 2021-09-10

奇怪的是,如果它是硬编码的,而不是从我的文件中获得它,为什么它还能工作(参见下面的代码):

代码语言:javascript
复制
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";
    } 

提前感谢!

EN

回答 1

Stack Overflow用户

发布于 2021-09-17 09:41:47

请看更正后的代码,OP的问题是日期没有经过清理,并且包含空格和新行。

函数split采用非常灵活的正则表达式形式的分隔符,这在这种情况下非常有用

注意:

  • OP必须以use strict;use warnings;开始代码,否则一些不受欢迎的行为可能会在

中出现

  • OP用my $variable;声明了一些变量,但其他变量没有声明--在代码中的某个地方,他/她很可能会在局部作用域中重新定义一个变量,这会导致意外行为

代码语言:javascript
复制
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";
        }           
    }
}

输出

代码语言:javascript
复制
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);来分配更有意义的变量名,以使代码更具可读性和更易于维护

注意:请查看以下代码样式是否对您有意义

代码语言:javascript
复制
        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

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

https://stackoverflow.com/questions/69219962

复制
相关文章

相似问题

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