【发布时间】:2012-02-04 14:03:45
【问题描述】:
在 Perl 中,我尝试使用以下代码将包含毫秒纪元时间变量 $adjSendTime 的变量转换为标准约定:
$timeLabel = sprintf("%02d:%02d:%02d", (($adjSendTime/3600000) % 24), (($adjSendTime/60000) % 60), $currentSecond);
问题在于,只要到达第 59 秒,时间的分钟部分就会比应有的时间高一分钟。输出看起来像
11:58:57
11:58:58
11:59:59
11:59:00
11:59:01
$adjSendTime的计算如下:
# Determine number of hours between local time and UTC.
# This code is needed to compare timestamps in local time with those in epoch time.
# This code only works in time zones with current time less than UTC time.
@timeArray = gmtime();
$utcHour = $timeArray[2];
@timeArray = localtime();
$localHour = $timeArray[2];
# calculate number of milliseconds between current time and UTC time
$utcShift = ($utcHour - $localHour + 24) % 24;
$utcShift = $utcShift*60*60*1000;
...
if ($field[$i] =~ /^\[29997]=/) {
$sendTimestamp = $field[$i];
$sendTimestamp =~ s/.*=(\d*).*/$1/;
# convert send time to local time.
$adjSendTime = $sendTimestamp - $utcShift;
}
$currentSecond 的计算在代码的两个不同部分中。第一个片段在$FIRST = 1; 时第一次出现在循环中。在执行此 if 语句后,$FIRST 永远不会再次重置为 1。
$second = ($adjSendTime/1000) % 60;
if ($FIRST) {
$currentSecond = $second;
$prevSeqId = $seqId;
$FIRST = 0;
}
在子例程 resetCounters 中,脚本中计算的每个值都重新初始化为 0。在输入日志文件中的每一秒开始时调用此子例程。
sub resetCounters
# -----------------------------------------------------------
# resets all metrics counters
# -----------------------------------------------------------
{
$tps = 0;
$mps = 0;
$batch = 0;
$maxBatch = 0;
$avgBatch = 0;
$latency = 0;
$latencySum = 0;
$maxLatency = 0;
$avgLatency = 0;
$overThreshold = 0;
$percentOver = 0;
$zeroLatencyCount = 0;
$currentSecond = $second;
@latencies = ();
}
谁能帮我弄清楚为什么 Perl 会这样做,因为当我通过长手除法找到余数时,我没有这个问题?我意识到我可以使用 datetime 来找到这个计算的小时和分钟,但我仍然有兴趣确定我的计算出了什么问题,这样我希望将来在使用 % 时可以避免这样的问题Perl。
【问题讨论】:
-
你从哪里得到
$currentSecond?看起来你正在以某种方式增加它而不改变$adjSendTime -
请显示完整循环的代码。看起来错误出现在您显示的语句之前的语句中。
-
我必须为我缺乏 Perl 经验向所有人道歉,而且我不能把我所有的代码都放给你们看。公司政策规定我只能在网上发布所需的部分代码来解决问题,而且越少越好..