Perl - 日期时间模块 - 将日期时间对象值分配给变量时出现问题



我有一个哈希值,看起来像:

%info = { 
'EVENT_START' => '27 Jul 2018 17:02:00.000',
'EVENT_END'   => '27 Jul 2018 17:05:30.220',
'EVENT'       => { 
'ACCELERATION_SEC' => '30.7',
'STILL_SEC' => '30.8195',
'STILL_END' => '27 Jul 2018 17:35:13.083'
}           
};

我尝试将这些哈希条目转换为 DateTime 对象,然后使用它们执行计算:

use DateTime::Format::Strptime;
use DateTime::Duration;
my $parse_time = DateTime::Format::Strptime->new(pattern => '%d %b %Y %H:%M:%S.%N');
my $event_start = $parse_time->parse_datetime($info{"EVENT_START"});
my $event_end   = $parse_time->parse_datetime($info{"EVENT_END"});
my $still_end   = $parse_time->parse_datetime($info{"EVENT"}{"STILL_END"});
($sec, undef) = split /./, $info{"EVENT"}{"ACCELERATION_SEC"};
$duration = DateTime::Duration->new( seconds => $sec );
print "1) event start $event_startn";
$lower_bound = $event_start;
$lower_bound->add_duration($duration);
print "2) event start $event_startn";
print "3) lower_bound $lower_boundn";
($sec, undef) = split /./, $info{"EVENT"}{"STILL_SEC"};
$duration = DateTime::Duration->new( seconds => $sec );
$upper_bound = $lower_bound;
$upper_bound->add_duration($duration);
print "4) lower_bound $lower_boundn";
print "5) upper_bound $upper_boundn";

其输出为:

1) event start 2018-07-27T17:02:00
2) event start 2018-07-27T17:02:30
3) lower_bound 2018-07-27T17:02:30
4) lower_bound 2018-07-27T17:03:00
5) upper_bound 2018-07-27T17:03:00

这看起来像$lower_bound = $event_start行(以及另一个类似的行(将引用分配给$event_start而不是$event_start的值,以$lower_bound。但我不确定如何传递此 DateTime 对象的值而不是对它的引用。

请参阅DateTime对象的clone方法:

$dt->克隆((

此对象方法返回一个新对象,该对象是调用该方法的对象的副本。

然后产生:

main::(-e:1):   1
DB<1> use DateTime
DB<2> $start = DateTime->now();
DB<3> print $start;
2018-08-09T19:05:03
DB<4> $later = $start;
DB<5> $later->add(years => 1000);
DB<6> print $later;
3018-08-09T19:05:03
DB<7> print $start;
3018-08-09T19:05:03
DB<8> $start = DateTime->now();
DB<9> $later = $start->clone();
DB<10> $later->add(years => 1000);
DB<11> print $later;
3018-08-09T19:05:39
DB<12> print $start;
2018-08-09T19:05:39

至于原因,从概念上讲,如果你记得基本上Perl中的一个对象是对哈希的引用(对于极少数情况下,它仍然是对某物的引用,下面以相同的方式适用(,所以当你做$to = $from就像做$ref2_to_hash = $ref1_to_hash当然,如果你将任何东西更改为$ref1_to_hash哈希,它将应用于另一个变量,因为它们是 2 个不同的变量(2 个单独的名称(,但值是对(单个(哈希的相同引用。

或更清晰:

main::(-e:1):   1
DB<1> $ref1 = { foo => 42 }
DB<2> print $ref1
HASH(0x7fce9800af68)
DB<3> $ref2 = $ref1
DB<4> print $ref2
HASH(0x7fce9800af68)
DB<5> $ref1->{foo} = 'bar';
DB<6> print %$ref1;
foobar
DB<7> print %$ref2;
foobar

通常,对象是哈希上的祝福引用,如果我们在上面添加bless,结果是相同的:

main::(-e:1):   1
DB<1> $ref1 = { foo => 42 }
DB<2> print $ref1;
HASH(0x7f939e80af68)
DB<3> bless($ref1, 'whatever');
DB<4> print $ref1;
whatever=HASH(0x7f939e80af68)
DB<5> $ref2 = $ref1;
DB<6> print $ref2;
whatever=HASH(0x7f939e80af68)

请注意,输出会发生变化,以显示哈希引用在某些命名空间中受到祝福,但它对地址(它指向的基础哈希(没有影响。

(当然,为了完整,但特别棘手的是,可以使用overload=操作期间/之后更改行为,然后像克隆一样自动执行其他操作。请参阅man overloading中的"复制构造函数"以及"回退"的后果。

回到DateTime,虽然与您的问题无关,但上面也表明您可以直接使用add(),它是带有DateTime::Duration对象的add_duration快捷方式。

最新更新