Hi Edgar,
Edgar Meij wrote:
Months will be converted to days with factor 30.5 which will sure give more "precise" result
Thought of that as well, but I read this from the DateManip pages:
...it is NOT known how many days form a month. As a result, the part of the delta containing month/year and the part with sec/min/hr/day must be treated separately. For example, ``Mar 31, 12:00:00'' plus a delta of 1month 2days would yield ``May 2 12:00:00''. The year/month is first handled while keeping the same date. Mar 31 plus one month is Apr 31 (but since Apr only has 30 days, it becomes Apr 30). Apr 30 + 2 days is May 2. As a result, in the case where two dates are entered, the resulting delta can take on two different forms...
Hmm indeed. I've played a little with Date::Manip and this is what I've got:
date_begin=20040301 date_end=20040401 DateCalc(mode-0): +0:0:4:3:0:0:0 -> 2678400 DateCalc(mode-1): +0:1:0:0:0:0:0 -> 2629800 DateCalc(mode-2): +0:1:0:0:0:0:0 -> 2629800
The usual(1) and business(2) mode returned 1 month which got multiplied by 30.5 days/month, and that gave an error. I'd call it rather insignificant in this context (response times that span across such large interval).
date_begin=20040401 date_end=20040501 DateCalc(mode-0): +0:0:4:2:0:0:0 -> 2592000 DateCalc(mode-1): +0:1:0:0:0:0:0 -> 2629800 DateCalc(mode-2): +0:1:0:0:0:0:0 -> 2629800
The error will be approx +/- 0.5 day (or greater when February comes in). Talking about differences between calculcated seconds for mode-0 (real) and mode-1 (with months approximated).
For usual things (cases resolved in less than a month) there's no error:
date_begin=20041129 date_end=20041202 DateCalc(mode-0): +0:0:0:3:0:0:0 -> 259200 DateCalc(mode-1): +0:0:0:3:0:0:0 -> 259200 DateCalc(mode-2): +0:0:0:3:0:0:0 -> 259200
date_begin=20041029 date_end=20041102
DateCalc(mode-/): +0:0:0:4:0:0:0 -> 345600
DateCalc(mode-1): +0:0:0:4:0:0:0 -> 345600
DateCalc(mode-2): +0:0:0:2:0:0:0 -> 172800
(-2 due to: All Saints' Day and a Sunday) date_begin=20040430 date_end=20040505
DateCalc(mode-0): +0:0:0:5:0:0:0 -> 432000
DateCalc(mode-1): +0:0:0:5:0:0:0 -> 432000
DateCalc(mode-2): +0:0:0:3:0:0:0 -> 259200
(-2 due to: Labour Day and a Sunday)date_begin=20040330 date_end=20040505 DateCalc(mode-/): +0:0:5:1:0:0:0 -> 3110400 DateCalc(mode-1): +0:1:0:5:0:0:0 -> 3061800 DateCalc(mode-2): +0:1:0:3:0:0:0 -> 2889000
The question is: does it matter? It's an error of less than 5% on large intervals which will be extremely rare (I hope), and as such removed from statistical analysis as extremes (to prevent them from spoiling bell shaped normal-like distribution curve).
If it does, how can we improve precision on that? The obvious answer is to use all three modes: business, usual and precise and determine is there a difference between the first two, and if there is -- break the interval into months and calculate real length of each in a loop. But, would it make more sense? For me, business month is no different than real month. It only matters when a weekend cuts in in mid-sized intervals of time.
In the attachment is the Perl script which I used for testing.
Kind Regards,
Damir
#!/usr/bin/perl -w
use strict;
use warnings;
use Date::Manip;
my ($date_a, $date_b, $delta, $err, $sec);
$date_a = ParseDate('2004-10-29 11:59:59')
or die "Date A bad!\n";
$date_b = ParseDate('2004-11-02 11:59:59')
or die "Date B bad!\n";
print "\n date_begin=$date_a date_end=$date_b\n";
$delta = DateCalc($date_a,$date_b,\$err)
or die "Failed DateCalc(/):$err, $!";
$sec = interval_to_sec($delta);
print " DateCalc(mode-0): $delta -> $sec\n";
$delta = DateCalc($date_a,$date_b,\$err, 1)
or die "Failed DateCalc(1):$err, $!";
$sec = interval_to_sec($delta);
print " DateCalc(mode-1): $delta -> $sec\n";
$delta = DateCalc($date_a,$date_b,\$err, 2)
or die "Failed DateCalc(2):$err, $!";
$sec = interval_to_sec($delta);
print " DateCalc(mode-2): $delta -> $sec\n";
# parse interval string and yield seconds
sub interval_to_sec {
my ($intv) = @_;
my ($sec) = 0;
my $sign = ($intv =~ /^-/) ? -1 : 1;
my @f = reverse(split(/:/, $intv));
# use just 5 least significant fields
$sec = $f[0];
$sec += $f[1] * 60;
$sec += $f[2] * 3600;
$sec += $f[3] * 86400;
$sec += $f[4] * 604800; # 7 days
$sec += $f[5] * 2629800; # 30.4 days (365.25 / 12)
$sec += $f[6] * 31557600; # 365.25 days (Julian year)
return $sign * $sec;
}
_______________________________________________ OTRS mailing list: otrs - Webpage: http://otrs.org/ Archive: http://lists.otrs.org/pipermail/otrs To unsubscribe: http://lists.otrs.org/cgi-bin/listinfo/otrs Support oder Consulting f�r Ihr OTRS System? => http://www.otrs.de/
