为什么没有来自Template :: Plugin :: Date的date.format()返回我期望的持续时间?

时间:2016-07-19 12:06:36

标签: perl

我有一个持续时间以秒为单位,我试图使用Template Toolkit插件Template::Plugin::Date转换为HH:MM:SS格式:

[% Use date %]
[% SET tseconds = 478966 %]
[% date.format(tseconds ,'%H:%M:%S') %]

这将返回13:02:46,但我预计它将返回133:02:46(478966秒等于133小时,2分钟和46秒)。有没有其他方法可以使用Template Toolkit将持续时间(以秒为单位)转换为HH:MM:SS格式?

1 个答案:

答案 0 :(得分:1)

没有一个插件会这样做,但你可以编写自己的函数并将其传递给信息哈希,就像这样

use strict;
use warnings 'all';

use Time::Seconds;
use Template;


my $vars = {
    format_hms => \&format_hms,
};

my $tt = Template->new;

$tt->process(\<<END_TEMPLATE, $vars);
[% SET tseconds = 478966 %]
[% format_hms(tseconds) %]
END_TEMPLATE


sub format_hms {

    my $t = Time::Seconds->new(shift);

    my $h = int $t->hours;
    $t -= $h * ONE_HOUR;

    my $m = int $t->minutes;
    $t -= $m * ONE_MINUTE;

    my $s = int $t->seconds;

    sprintf "%d:%02d:%02d\n", $h, $m, $s;
}

输出

133:02:46


更新

如果您希望通过自定义插件提供代码,而不是通过在%vars哈希中传递子例程引用,那么这是一个允许您执行此操作的简单模块

package Custom::Template::Plugin::Duration;

use strict;
use warnings 'all';

use base 'Template::Plugin';

use Time::Seconds;


sub format_hms {

    my $self = shift;

    my $t = Time::Seconds->new($_[0]);

    my $h = int $t->hours;
    $t -= $h * ONE_HOUR;

    my $m = int $t->minutes;
    $t -= $m * ONE_MINUTE;

    my $s = int $t->seconds;

    sprintf "%d:%02d:%02d\n", $h, $m, $s;
}

1;

如果将Custom/Template/Plugin/Duration.pm保存在@INC个目录中(当前工作目录是一个不错的选择),那么你可以编写这样的代码

use strict;
use warnings 'all';

use Template;

my $tt = Template->new(
    PLUGINS => {
        duration => 'Custom::Template::Plugin::Duration',
    }
);

$tt->process(\<<END_TEMPLATE);
[% USE duration %]
[% SET tseconds = 478966 %]
[% tseconds %] is equivalent to
[% duration.format_hms(tseconds) %]
END_TEMPLATE

输出

478966 is equivalent to
133:02:46

然而,除了模板被授予访问子程序的方式之外,这里没有什么本质上的不同。底层代码是相同的