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/