You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Perl DateTime模块计算时间差错误,如何获取正确小时数?

问题

尝试计算2024-01-03T19:00:00与2024-01-07T16:00:00的小时差(正确结果应为93小时),但使用Perl DateTime模块计算时,DateTime::Duration对象的多种方法都只返回21小时,完全忽略了间隔的天数。无论是通过字符串解析还是直接创建DateTime对象,结果都一致。

示例代码1

#!/usr/bin/env perl

use 5.038;
use warnings FATAL => 'all';
use autodie ':default';
use DDP;
use Devel::Confess 'color';
use DateTime;

sub str_to_date ($date) {
    if ($date =~ m/^(\d+) # year
    \-(\d{1,2})           # month
    \-(\d{1,2})           # day
    T
    (\d+)                        # hour
    :
    (\d+)                        # minutes
    :
    (\d+)                        # seconds                  
    /x) {
        return DateTime -> new(
        year  => $1,
        month => $2,
        day   => $3,
        hour    => $4,
        minute=> $5,
        second=> $6,
    );
    } else {
        die "$date failed regex.";
    }
} # later dates are "greater"
my $wed_date = str_to_date('2024-01-03T19:00:00');
say $wed_date->day;
my $sun_date = str_to_date('2024-01-07T16:00:00');
my $diff = $sun_date - $wed_date; # returns a duration object

p $diff;
say $diff->clock_duration->in_units('hours'); # 21, but should be 93
say $diff->in_units('hours'); # 21 again
say $diff->hours; # 21 again
say $sun_date->delta_days($wed_date)->in_units('hours'); # 0
p $diff->deltas;

示例代码2

#!/usr/bin/env perl
use 5.038;
use warnings FATAL => 'all';
use autodie ':default';
use DDP;
use Devel::Confess 'color';
use DateTime;

my $wed_date = DateTime->new(
    year => 2024,
    month=>1,
    day=>3,
    hour=>19
);#str_to_date('2024-01-03T19:00:00');
my $sun_date = DateTime->new(
    year=>2024,
    month=>1,
    day=>7,
    hour=>16#my $sun_date = str_to_date('2024-01-07T16:00:00');
);#
say $wed_date->day;

my $diff = $sun_date - $wed_date;

p $diff;
say $diff->clock_duration->in_units('hours'); # 21, but should be 93
say $diff->in_units('hours'); # 21 again
say $diff->hours; # 21 again
say $sun_date->delta_days($wed_date)->in_units('hours'); # 0
p $diff->deltas; # 10

查阅DateTime::Duration相关文档后仍无法得到正确结果,请问如何获取两个日期之间的正确小时数?

解决方案

问题核心是DateTime::Duration会将时间差拆分为天、小时、分钟等独立单位存储,而非直接合并为总小时数。比如你计算的时间差是3天21小时,hours()方法只会返回拆分后的21小时,不会包含天数转换的部分。

以下两种方法可获取正确的总小时数:

方法1:通过时间戳计算差值

将两个DateTime对象转换为UTC时间戳(从epoch开始的秒数),计算差值后除以3600得到总小时数:

my $total_hours = ($sun_date->epoch - $wed_date->epoch) / 3600;
say $total_hours; # 输出93

方法2:手动合并天和小时的差值

利用in_units方法同时提取天数和小时数,将天数转换为小时后相加:

my ($days, $hours) = $diff->in_units('days', 'hours');
my $total_hours = $days * 24 + $hours;
say $total_hours; # 输出93

补充说明

  • clock_duration()仅计算当天内的时间差,因此只会返回21小时,不适合跨天场景。
  • delta_days()仅返回天数差,不会自动转换为小时,直接调用in_units('hours')会返回0。

内容的提问来源于stack exchange,提问作者con

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 04:35:10