如何将时间戳四舍五入到最接近的 5 分钟值



>我有这种时间戳格式:

2019-01-24T00:00:05.011719

如何将其四舍五入到最接近的 5 分钟值?

编辑:好的,这个问题非常模糊和懒惰。但问题仍然存在,只是想为我的问题添加信息。

  1. 我不知道那是什么格式,所以如果我知道我可以谷歌,什么函数或方法可以转换这些日期格式。

  2. 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

最新更新