Re: DateCalc using Date::Manip
by hippo (Bishop) on Jan 10, 2017 at 10:28 UTC
|
| [reply] [Watch: Dir/Any] |
|
Try
print Delta_Format($dtopt,0,'+%yv:%Mv:+%wv:%dv:%hv:%mv:%sv');
instead of your print line.
It's probably not the newer Perl that bites you, but rather the newer Date::Manip module that you are using.
Try to check what you have in Date::Manip::DM6.
A bit strange; the raw value that I see for the delta calculated from the date values you provided is 0:0:0:110:0:0:0, which isn't equal with what your systems are giving.
| [reply] [Watch: Dir/Any] [d/l] |
|
I have tried what you said and it gives me
+0:0:+0:0:3648:0:0
| [reply] [Watch: Dir/Any] |
|
|
I think depending upon o or 1 the output changes.
I have now tried your same code and I get the same output as you.
Many Thanks,
T
| [reply] [Watch: Dir/Any] |
|
Hello,
Thank you for the reply. I have tried the code as you suggested. Below is my modification to the code
my $s2="2016080100:00:00";
my $e1="2016123100:00:00";
my $format = '%dh %hd %hh %ht %yd';
$duyx1 =(DateCalc($s2,$e1));
$duyx1 = Delta_Format($duyx1,'2',$format);
print "\nduyx1 = $duyx1\n";
The output that i get from the code above is
0.00 3648.00 3648.00 3648.00 0.00
But the actual output should be
+0:0:+21:5:1:0:0
I am not sure what i missing .
Really appreciate all your help.
Many Thanks,
Teju
| [reply] [Watch: Dir/Any] [d/l] |
|
Note that your output string contains seven fields and colons between its values.
Your $format string contains five placeholders and no colons between them.
If you want identical values, a first step would be to specify the appropriate output format.
Also, I think the %dh format is not a valid format specification for Date::Manip::DM5.
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: DateCalc using Date::Manip
by huck (Prior) on Jan 10, 2017 at 10:51 UTC
|
http://search.cpan.org/~sbeck/Date-Manip-6.56/lib/Date/Manip/Calc.pod
Exact, semi-exact, and approximate calculations
An exact calculation is one in which the delta used (or produced) is an exact delta. An exact delta is described in the Date::Manip::Delta manual, but the short explanation is that it is a delta which only involves fields of an exactly known length (hours, minutes, and seconds). Business deltas also include days in the exact part. The value of all other fields in the delta will be zero. ... $mode defaults to "exact".
Why the mode seems to be different between the versions i cannot say
A semi-exact calculation is one in which the deltas used (or produced) is a semi-exact delta. This is also described in the Date::Manip::Delta manual, but the short explanation is that it includes days and weeks (for standard calculations) or weeks (for business calculations) in addition to the exact fields.
Edit to add: Ah the mode change is explained in the reply by SBECK in the post that hippo referenced above, i knew i saw something before but couldnt find it
| [reply] [Watch: Dir/Any] |
Re: DateCalc using Date::Manip
by SBECK (Chaplain) on Jan 10, 2017 at 15:26 UTC
|
As others have noted, there are several ways to do calculations (exact, approximate, semi-approximate). Unfortunately, Date::Manip::DM6 (which is basically just an interface that is backward compatible with the older versions of Date::Manip) didn't currently support all of them (since they didn't even exist in older versions of Date::Manip).
The was no reason NOT to support them... I just had never thought to add them (and nobody had requested that). So I just did, and in the next version of Date::Manip, you'll be able to do:
my $dtopt= DateCalc($dt1,$dt2,'semi');
and get what you want. However, that won't work in the current version.
Getting what you want with the current version of Date::Manip::DM6 is harder because in the older module, there were only exact and approximate, and in newer versions there are exact, semi-approximate, and approximate, and it's challenging to get what you want. Really, the best way would be to do that calculation using the OO interface:
use Date::Manip::Date;
my $date1 = new Date::Manip::Date;
my $date2 = $date1->new_date();
$date1->parse($dt1);
$date2->parse($dt2);
my $delt = $date1->calc($date2,'semi');
my $delv = $delt->value();
print "$delv\n";
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
use Date::Manip;
my $dt1="2016080100:00:00";
my $dt2='2016123100:00:00';
my $date1 = new Date::Manip::Date;
my $date2 = $date1->new_date();
$date1->parse($dt1);
$date2->parse($dt2);
my $delts = $date1->calc($date2,'semi');
my $delte = $date1->calc($date2,'exact');
my $delve=$delte->value();
my $delvs=$delts->value();
sub semi_exact {
my $delve=shift;
my @parts=split(':',$delve);
my $h0=$parts[4]+$parts[3]*24+$parts[2]*7*24;
my $w=sprintf('%d',$h0/(7*24));
$h0=$h0-$w*7*24;
if ($w<0) {$h0=$h0*-1;}
my $d=sprintf('%d',$h0/24);
$h0=$h0-$d*24;
my $delvse="0:0:$w:$d:$h0:$parts[5]:$parts[6]";
return $delvse;
} # semi-exact
my $delvse=semi_exact($delve);
print 'exact :'.$delve."\n";
print 'semi-approx:'.$delvs."\n";
print 'semi-exact :'.$delvse."\n";
my $fe=DateCalc($dt1,$dt2,0);
my $fse=semi_exact($fe);
print 'functional semi-exact :'.$fse."\n";
exit;
output
exact :0:0:0:0:3649:0:0
semi-approx:0:0:21:5:0:0:0
semi-exact :0:0:21:5:1:0:0
functional semi-exact :0:0:21:5:1:0:0
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
I don't have a 'semi-exact' mode in Date::Manip... but what you're really saying is: convert an exact delta to a semi-approximate one.
This is of course different from coming up with an semi-approximate delta from two dates (which is what I was doing... I should have noticed that it wasn't exactly what the OP was doing, but I got ahead of myself after noticing I couldn't use 'semi' mode in the older DateCalc).
In any case, you can do the following:
use Date::Manip;
my $dt1='2016080100:00:00';
my $dt2='2016123100:00:00';
my $exact= DateCalc($dt1,$dt2);
my $semi = DateCalc($dt1,$dt2,'semi');
print "Exact : $exact\n";
print "Semi : $semi\n";
my $delta = ParseDateDelta($exact,'semi');
print "Exact->Semi: $delta\n";
print "\n";
use Date::Manip::Date;
my $date1 = new Date::Manip::Date;
my $date2 = $date1->new_date();
$date1->parse($dt1);
$date2->parse($dt2);
my $delt_x = $date1->calc($date2);
my $delt_s = $date1->calc($date2,'semi');
my $val = $delt_x->value();
print "New Exact : $val\n";
$val = $delt_s->value();
print "New Semi : $val\n";
$delt_x->convert('semi');
$val = $delt_x->value();
print "New Ex->Se: $val\n";
which yields:
Exact : 0:0:0:0:3649:0:0
Semi : 0:0:21:5:0:0:0
Exact->Semi: 0:0:21:5:1:0:0
New Exact : 0:0:0:0:3649:0:0
New Semi : 0:0:21:5:0:0:0
New Ex->Se: 0:0:21:5:1:0:0
So you can see how to convert an exact delta to a semi-approximate one using either the old or new interfaces.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
A BIG THANK YOU!!!!!
I was able to sort out my problem with your code. Although, I need to make some modification to my code after it does the date calculation(with the code you have given) .
I will keep you updated.
MANY THANKS!!!!!!:)
| [reply] [Watch: Dir/Any] |
Re: DateCalc using Date::Manip
by 1nickt (Canon) on Jan 10, 2017 at 13:00 UTC
|
$ perl -Mwarnings -Mstrict -ML -E'
my $parser = DateTime::Format::Strptime->new(pattern => "%Y%m%d%H:%M:%
+S", on_error => "croak");
my $dt1 = $parser->parse_datetime("2016080100:00:00");
my $dt2 = $parser->parse_datetime("2016123100:00:00");
say $dt2->delta_days( $dt1 )->in_units("days");
'
Output:
152
[ Note that you still have to use in_units() because delta_days() returns a DateTime::Duration object (with all values rolled into a whole number of days). ]
Hope this helps!
The way forward always starts with a minimal test.
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: DateCalc using Date::Manip
by LanX (Saint) on Jan 10, 2017 at 11:23 UTC
|
Does the output you show really belong to the displayed code?
As a side note, you should tell us which versions of Date::Manip you are using.
update
The delta of the dates is roughly 5 months or 152 days.
6576 hours are roughly 274 days
21 month + 5 days are roughly 645 days.
update
Just realising this delta format has 7 fields, tried to understand the pod and gave up.
update
Aha. .. weeks ?!
> A delta consists of 7 fields: years, months, weeks, days, hours, minutes, and seconds, usually expressed as a colon-separated string. For example: | [reply] [Watch: Dir/Any] |
|
Hi,
It makes sense to me what you are saying. But i guess i need to display the output in a different format so it caters for the below output
+0:0:+21:5:1:0:0
| [reply] [Watch: Dir/Any] [d/l] |
|
my $dtopt= DateCalc($dt1,$dt2,1);
or maybe these will work
my $dtopt= DateCalc($dt1,$dt2,'semi');
or
my $dtopt= DateCalc($dt1,$dt2,'approx');
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
|
|
|
| [reply] [Watch: Dir/Any] |
|
|
|
|
|
|
|
|
|