Harry Putnam wrote:
I may have turned the question around from the usual approach, but I'm
having trouble seeing why my script gives the right answer.
The script reads data that contains dates in the format YYMMDD N, the
N isn't part of the date but is also a digit.
What the script tries to do is read the dates, run them thru
Time::Local to convert to epochal dates.
Then using the random number... create an offset in epochal time that
represents that many days.
100418 2
Would get converted to an offset of 2 * 86400... 2 days worth of
seconds.
That answer is then subtracted from the epochal time conversion
And then we print the converted date back in YYMMDD format.
In the above case it should be 100416
All that seems to work ok, whats puzzling me is that the function
`localtime' normally spits out the mnths in 0..11 notation, so in
other scripts I've written where something was converted I've has to
to add a little extra math step to make the mnths come out right.
$mon += 1;
But in this script, I was all set to do that but discovered the mnths
come out right only if I DON'T do it.
I'm feeding like localtime($var), a calculated epochal time. But it
appears to be spitting out the mnth element in (1...12) notation.
I'm sure there is some simple explanation but I'm not seeing it.
The main problem is that you are not testing edge cases like:
ev 101201 3
Or:
ev 100101 3
If you did you would get an error message like:
Month '12' out of range 0..11 at Why_is_the_answer_right.pl line 74
incoming data might look like the lines below... and the scripts
output follows at the very end.
------- --------- ---=--- --------- --------
ev 100409 3
send state tax payment by 15th
ev 100604
Newsguy account expires 100607
ev 100421 4
my appt is today
------- --------- ---=--- --------- --------
The real script is quite a lot longer uses getopts and does more
stuff. Here I've simplified, shortened and just used <> and fed a
file.
cat myscript:
#!/usr/local/bin/perl
use strict;
use warnings;
use Time::Local;
my $sec = 01;
my $min = 01;
my $hour = 01;
Why are you using octal numbers instead of decimal numbers? Using an
hour of 1 might conflict with the change of time from/to daylights
saving time. Better to use an hour in the middle of the day like 12 for
example, or use gmtime/timegm instead which doesn't change for daylight
savings.
while(<>){
if( my ($year,$mon,$mday,$predays) = $_ =~
m/^ev\s+(\d\d)(\d\d)(\d\d)\s+(\d)\s*$/){
my ($oyear,$omon,$omday) = ($year,$mon,$mday);
my $time = timelocal($sec,$min,$hour,$mday,$mon,$year);
You need to adjust the month and year correctly:
my $time = timelocal( $sec, $min, $hour, $mday, $mon - 1,
"20$year" - 1900 );
## calc based on 86400 second in 24 hr
my $offset = ($time - ($predays * 86400));
## We turn the offset time back into YYMMDD for comparison
($year,$mon,$mday) = (localtime($offset))[5,4,3];
$year -= 100;
That is not the correct way to adjust the year value:
perldoc -f localtime
# $mon += 1;
my $PaddedDateStr = sprintf "%02d%02d%02d", $year,$mon,$mday;
my $incoming_date = $oyear . $omon . $omday;
my $str = "\n Lets see how it works:
------- ----=---- -------
Incoming year mon day = $incoming_date
predays ($predays) * 86400
gives us this
offset $offset
Which leaves us with = $PaddedDateStr
------- ----=---- -------
";
print $str;
($year,$mon,$mday,$predays,$oyear,$omon,$omday,$offset,$incoming_date,$str)
= '';
The list on the right of the assinment has only one element so only
$year is assigned a value. But you are using lexical variables so that
line is superfluous.
}
}
print "\n";
------- --------- ---=--- --------- --------
./myscript file
Lets see how it works:
------- ----=---- -------
Incoming year mon day = 100409
predays (3) * 86400
gives us this
offset 1273125661
Which leaves us with = 100406
------- ----=---- -------
Lets see how it works:
------- ----=---- -------
Incoming year mon day = 100421
predays (4) * 86400
gives us this
offset 1274076061
Which leaves us with = 100417
------- ----=---- -------
John
--
The programmer is fighting against the two most
destructive forces in the universe: entropy and
human stupidity. -- Damian Conway
--
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/