Reputation: 11
I am trying to calculate and display, in minutes, the difference between the entered date and the present time. I have:
print "Enter a date YYYY MM DD. Remember perl's months go from 0-11.\n";
while ( @dateEnt < 1 ) {
my $dateEntered = <STDIN>;
chomp $dateEntered;
push @dateEnt, $dateEntered;
(@datedata) = split( /\s+/, $dateEntered );
$year = $datedata[0];
$month = $datedata[1];
$day = $datedata[2];
}
$time = time;
$readabletime = localtime($time);
use Time::Local;
$timeB = localtime [1];
$timeBetween = $readabletime[1] - $timeB;
print "The time between the dates is $timeBetween\n";
When I execute this, I get nothing for an answer. Any help?
Upvotes: 1
Views: 1888
Reputation: 53508
use strict;
and use warnings;
would have told you about a lot of the problems.
while
loop is redundant, because you push
without any validation. So it'll always be true on the second iteration. @dateEnt
redundant.localtime
in a scalar context gives a string. You cannot do maths with a string. (Occasionally you can cheat, because perl
can convert it to a number, but that doesn't work with a date string).use
is usually at the top of a program, because it's the first thing 'done' regardlesslocaltime
in an array context returns an array of values. ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
you can do (localtime)[1]
which gives you $min
. But that's not too meaningful for comparing anyway. $readabletime[1]
refers to the second element of an array called @readabletime
. This doesn't exist. So to accomplish what you're after - I would suggest using Time::Piece
(core perl module) like this:
#!/usr/bin/perl
use strict;
use warnings;
use Time::Piece
my $date;
while ( not $date ) {
print "Enter a date YYYY MM DD\n";
my $dateEntered = <STDIN>;
chomp $dateEntered;
$date = Time::Piece->strptime( $dateEntered, "%Y %m %d" );
}
print "Understood: $date\n";
my $timebetween_s = ( time() - $date->epoch );
print $timebetween_s, "s between then and now\n";
Note - it uses strptime
to convert the entered date to a Time::Piece
object (which you can just print
if you want and get a stringified date, but you can also do other transformations). strptime
supports lots of different formats.
But you just subtract $date->epoch
- which gets the time in seconds since 1st Jan 1970, from time()
which is also the time in seconds since 1st Jan 1970. This gives you a time delta like you want - in seconds. You'll need to divide it if you want different units.
Upvotes: 3
Reputation: 492
you can try this
use strict;
use warnings;
use DateTime;
my $from_date = DateTime->new(
year => 2014,
month => 9,
day => 24,
hour => 9,
minute => 13,
second => 8,
time_zone => 'local',
);
print "$from_date\n";
my $current_date = DateTime->now( time_zone => 'local' )->set_time_zone('floating');
print "$current_date\n";
my $time_diff = $current_date - $from_date;
print 'year = ', $time_diff->years, "\n";
print 'month = ', $time_diff->months, "\n";
print 'days = ', $time_diff->days, "\n";
print 'hours = ', $time_diff->hours, "\n";
print 'minutes = ', $time_diff->minutes, "\n";
print 'secondss = ', $time_diff->seconds, "\n";
Result:
2014-09-24T09:13:08
2015-09-25T21:31:37
year = 1
month = 0
days = 1
hours = 12
minutes = 18
secondss = 29
Upvotes: 1
Reputation: 126772
Lets take a look at this last chunk
use Time::Local;
$timeB = localtime[1];
$timeBetween = $readabletime[1] - $timeB;
print "The time between the dates is $timeBetween\n";
The use
statement is normally put at the top of the program because it's actually executed at compile time, but it's fine anywhere really
localtime[1]
looks like you're trying to access the second element (Perl arrays start at index zero) of an array called localtime
. But what you're actually doing is creating an anonymous array that contains the single value 1 and passing a reference to it to localtime
. If you try print[1]
instead, you'll see that you get something like ARRAY(0x22c4000)
. So localtime
is trying to convert a memory address into a date and time
$readabletime[1]
is attempting to access the second element of array @readabletime
, which doesn't exists so it will evaluate to undef
You end up trying to subtract something like the string "Thu Mar 4 18:50:24 1971"
from undef
which is meaningless. I think you should get a fatal error something like
Argument "Thu Mar 4 18:50:24 1971" isn't numeric in subtraction
Upvotes: 3