Perl-DateTime模块-将DateTime对象值分配给变量时遇到麻烦

时间:2018-08-09 18:59:35

标签: perl datetime

我的哈希看起来像:

%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_start\n";

$lower_bound = $event_start;
$lower_bound->add_duration($duration);

print "2) event start $event_start\n";
print "3) lower_bound $lower_bound\n";

($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_bound\n";
print "5) upper_bound $upper_bound\n";

此输出为:

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对象的值而不是对其的引用。

1 个答案:

答案 0 :(得分:1)

请参见clone对象的DateTime方法:

  

$ dt-> clone()

     

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

然后产生:

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(),它是add_durationDateTime::Duration的捷径对象。