Reputation: 57
I have a function and the string fed into it is a date in US format from Sybase. I'm simply trying to put it into numeric format so I can do a date comparison. For example, if I sent Sep 12 2019
string as an argument, I would expect the output to be 9-12-2019
. However, $mon
appears to be always empty. I tried using chomp
on $ms
in case it somehow had a CR on the end, but that made no difference.
sub rnumeric
{ my ($d) = @_; # The parameter fed to this function
print "Date to convert is $d ";
my $ms = substr $d, 0, 3;
if ($ms eq "Jan") { my $mon = "1" };
if ($ms eq "Feb") { my $mon = "2" };
if ($ms eq "Mar") { my $mon = "3" };
if ($ms eq "Apr") { my $mon = "4" };
if ($ms eq "May") { my $mon = "5" };
if ($ms eq "Jun") { my $mon = "6" };
if ($ms eq "Jul") { my $mon = "7" };
if ($ms eq "Aug") { my $mon = "8" };
if ($ms eq "Sep") { my $mon = "9" };
if ($ms eq "Oct") { my $mon = "10"};
if ($ms eq "Nov") { my $mon = "11"};
if ($ms eq "Dec") { my $mon = "12"};
my $day = trim(substr $d, 4, 2);
my $yr = substr $d, 7, 4;
my $d = $mon."-".$day."-".$yr;
return $d;
}
Edit - sample output from "Print" statements.
Item overdue Date to convert is Jan 9 2015 11:59:00:000PM Our due date is -9-2015
Item overdue Date to convert is Feb 6 2014 11:59:00:000PM Our due date is -6-2014
Item overdue Date to convert is Feb 6 2014 11:59:00:000PM Our due date is -6-2014
Item overdue Date to convert is Jan 12 2015 11:59:00:000PM Our due date is -12-2015
Item overdue Date to convert is Jan 12 2015 11:59:00:000PM Our due date is -12-2015
Item overdue Date to convert is Sep 8 2016 11:59:00:000PM Our due date is -8-2016
Item overdue Date to convert is Sep 8 2016 11:59:00:000PM Our due date is -8-2016
Item overdue Date to convert is Oct 4 2013 11:59:00:000PM Our due date is -4-2013
I got the trim
function from a helpful post online-I've used it for a while and it does work, although the regular expression logic it uses is beyond me.
sub trim
{ my $s = shift; $s =~ s/^\s+|\s+$//g; return $s };
Unfortunately I can't use use strict
because I have to open the Sybase database with code provided by the host, who didn't use it, meaning that it throws up problems with their code that I can't fix.
Upvotes: 1
Views: 73
Reputation: 132832
If you store the name to number mapping in a hash, you can simply lookup the number. Most of your code then disappears:
use v5.10;
print rnumeric( 'Sep 12 2019' );
sub rnumeric {
state %Months = map { state $n = 1; $_ => $n++ } qw(
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec );
my( $month_name, $day, $year ) = split /\s+/, $_[0];
join '-', $Months{$month_name}, $day, $year;
}
If you don't like that map
, you can assign the numbers yourself:
use v5.10;
print rnumeric( 'Sep 12 2019' );
sub rnumeric {
state %Months = qw(
Jan 1 Feb 2 Mar 3 Apr 4 May 5 Jun 6
Jul 7 Aug 8 Sep 9 Oct 10 Nov 11 Dec 12);
my( $month_name, $day, $year ) = split /\s+/, $_[0];
join '-', $Months{$month_name}, $day, $year;
}
But, I'd rather let something else think about this. The Time::Piece module from the Standard Library can do it. Give it a format to recognize and parse the date, then another format to put it back together:
use v5.10;
use Time::Piece;
print rnumeric( 'Sep 12 2019' );
sub rnumeric {
Time::Piece
->strptime( $_[0], "%b %d %Y" )
->strftime( '%-m-%-d-%Y' )
}
The format like %-m
uses the hyphen to strip leading zeros. If you want the leading zeros, it would be just %m
.
Upvotes: 3
Reputation: 62096
You need to use strict
and warnings
. These will show you where your mistakes are. You need to scope your variables properly. It is good that you declare variables with my
, but you should only declare each variable once.
use warnings;
use strict;
print rnumeric('Sep 12 2019');
print "\n";
sub rnumeric
{ my ($d) = @_; # The parameter fed to this function
print "Date to convert is $d ";
my $ms = substr $d, 0, 3;
my $mon;
if ($ms eq "Jan") { $mon = "1" };
if ($ms eq "Feb") { $mon = "2" };
if ($ms eq "Mar") { $mon = "3" };
if ($ms eq "Apr") { $mon = "4" };
if ($ms eq "May") { $mon = "5" };
if ($ms eq "Jun") { $mon = "6" };
if ($ms eq "Jul") { $mon = "7" };
if ($ms eq "Aug") { $mon = "8" };
if ($ms eq "Sep") { $mon = "9" };
if ($ms eq "Oct") { $mon = "10"};
if ($ms eq "Nov") { $mon = "11"};
if ($ms eq "Dec") { $mon = "12"};
my $day = trim(substr $d, 4, 2);
my $yr = substr $d, 7, 4;
$d = $mon."-".$day."-".$yr;
return $d;
}
Upvotes: 2