>我有这种时间戳格式:
2019-01-24T00:00:05.011719
如何将其四舍五入到最接近的 5 分钟值?
编辑:好的,这个问题非常模糊和懒惰。但问题仍然存在,只是想为我的问题添加信息。
-
我不知道那是什么格式,所以如果我知道我可以谷歌,什么函数或方法可以转换这些日期格式。
-
20190124000000这不是正确的 5 分钟值吗?顺便说一下,我希望它像那种格式。但是它太容易成为正确的方法,这让我怀疑像在大学里回答数学问题一样。无论如何,我可以为此使用正则表达式。
use DateTime::Format::Strptime qw( );
my $format = DateTime::Format::Strptime->new(
pattern => '%FT%T.%6N',
time_zone => 'UTC', # Or 'local' or 'America/Toronto' or '-0500'
on_error => 'croak',
);
my $dt = $format->parse_datetime('2019-01-24T00:00:05.011719');
$dt->set_formatter($format); # Set default stringification format.
$dt->truncate( to => 'second' )->add( seconds => 1 ) if $dt->nanosecond;
$dt->truncate( to => 'minute' )->add( minutes => 1 ) if $dt->second;
$dt->add( minutes => 5 - ( $dt->minute % 5 ) ) if $dt->minute % 5;
say $dt; # 2019-01-24T00:05:00.000000
请注意,如果关联的时区遵守 DST(因为秋季重复一小时),则2019-01-24T00:00:05.011719
使用的格式不明确。
除此之外,上面的代码可以正确处理时间流逝中的不连续性,例如在 DST 更改时发生的不连续性,只要不连续性在舍入点开始和结束。
问题可以分解为:
- 选择时间段
N
时间单位 - 选择第一个(第 0 个)时间段开始的起点(纪元)
- 解析时间戳并将其转换为" 自纪元以来
X
时间单位"X
的整数除以N
得到时间戳所在的时间段的 #X
除以N
的余数为您提供该时间段内的偏移量- 如果余数正好是
0
(零),则时间戳位于该周期的开头
您的要求是
N
为 5 分钟或 300 秒- 让我们使用标准的 UNIX 纪元,即
1970-01-01T00:00:00Z
- 您希望向上舍入到下一个周期,除非时间戳恰好是周期的开始。
- 由于您没有给出时区,为了简单起见,我假设 UTC。
仅使用核心Perl,即Time::P iece,解决方案将是:
#!/usr/bin/perl
use warnings;
use strict;
use constant PERIOD => 5 * 60; # 5 minutes
use Time::Piece;
# timezone for Time::Piece->new()
$ENV{TZ} = "UTC";
while (<DATA>) {
chomp;
my($iso8601, $fractional) = split(/./);
# NOTE: time is interpreted as UTC
my $t = Time::Piece->strptime($iso8601, '%FT%T');
# calculate multiple of PERIOD and offset in that period
my $index = int($t->epoch / PERIOD);
my $offset = $t->epoch % PERIOD + "0.${fractional}";
# round up to next PERIOD unless time is exactly multiple of PERIOD
$index++ if $offset > 0;
# convert index back to epoch and generate new Time::Piece object
# NOTE: timezone offset is set to $ENV{TZ} timezone
my $t2 = Time::Piece->new($index * PERIOD, 0);
print "$_ -> ", $t2->strftime('%FT%T'), "n";
}
exit 0;
__DATA__
2019-01-24T00:00:00.000000
2019-01-24T00:00:05.011719
2019-01-24T00:04:59.999999
2019-01-24T00:05:00.000000
2019-07-24T00:00:00.000000
2019-07-24T00:00:05.011719
2019-07-24T00:04:59.999999
2019-07-24T00:05:00.000000
试运转:
$ perl dummy.pl
2019-01-24T00:00:00.000000 -> 2019-01-24T00:00:00
2019-01-24T00:00:05.011719 -> 2019-01-24T00:05:00
2019-01-24T00:04:59.999999 -> 2019-01-24T00:05:00
2019-01-24T00:05:00.000000 -> 2019-01-24T00:05:00
2019-07-24T00:00:00.000000 -> 2019-07-24T00:00:00
2019-07-24T00:00:05.011719 -> 2019-07-24T00:05:00
2019-07-24T00:04:59.999999 -> 2019-07-24T00:05:00
2019-07-24T00:05:00.000000 -> 2019-07-24T00:05:00