sub confusion

G

Guest

I couldn't find the solution to this on google, so... There must be
some way to write two simple functions to convert a single digit date
to a two digit date and strip the ":" characters from time.

Thanks in advance,
Walter

#!perl
$today=`date`;
($weekday, $month, $day, $time, $junk) = split(' ', $today, 5);
$daynum = DayToNum( $day );
$timenum = TimeToNum( $time );

## 1 -> 01
print "\$daynum\( $day \) = $daynum \n";
## 12:16:56 -> 121656
print "\$timenum\( $time \) = $timenum \n";

sub DayToNum {
## doesn't work
if ( length lt 2 ) { $_ = "0" . "$_"; }
## doesn't work
# if (/^1$/) { return "01"; }
# elsif (/^2$/) { return "02"; }
# elsif (/^3$/) { return "03"; }
# elsif (/^4$/) { return "04"; }
# elsif (/^5$/) { return "05"; }
# elsif (/^6$/) { return "06"; }
# elsif (/^7$/) { return "07"; }
# elsif (/^8$/) { return "08"; }
# elsif (/^9$/) { return "09"; }
# else { return "$_"; }
}
sub TimeToNum {
## doesn't work
s/://g;
## doesn't work
# $_ =~ s/://g;
## works...
# $timenum = $time;
# $timenum=~ s/://g;
}
 
B

Bob Walton

I couldn't find the solution to this on google, so... There must be
some way to write two simple functions to convert a single digit date
to a two digit date and strip the ":" characters from time. ....
Walter

#!perl
$today=`date`;


You might consider using Perl's builtin localtime() function rather than
your OS's date command -- it doesn't fire off a process, and is far more
portable. Further, if you evaluate localtime() is a list context, you
will directly get the numeric information you are looking for. See:

perldoc -f localtime

($weekday, $month, $day, $time, $junk) = split(' ', $today, 5);
$daynum = DayToNum( $day );
$timenum = TimeToNum( $time );

## 1 -> 01
print "\$daynum\( $day \) = $daynum \n";

-----------------^-------^

It is not necessary to backslash-quote parens in a double-quoted string.

## 12:16:56 -> 121656
print "\$timenum\( $time \) = $timenum \n";
------------------^--------^

Ditto.



sub DayToNum {
## doesn't work


That's because you need to pick up the argument to your sub. Something
like:

$_=shift;

or

$_=$_[0];

should do the trick.

if ( length lt 2 ) { $_ = "0" . "$_"; }

<-----------------^^

If you want to do a numeric comparison, you need to use a numeric
comparison operator like < rather than a string comparison operator like
lt. Also, in "$_" you have a "useless use of double-quoted string".
While not normally a problem, it does have its subtle little points, and
should not normally be done.

## doesn't work
# if (/^1$/) { return "01"; }
# elsif (/^2$/) { return "02"; }
# elsif (/^3$/) { return "03"; }
# elsif (/^4$/) { return "04"; }
# elsif (/^5$/) { return "05"; }
# elsif (/^6$/) { return "06"; }
# elsif (/^7$/) { return "07"; }
# elsif (/^8$/) { return "08"; }
# elsif (/^9$/) { return "09"; }
# else { return "$_"; }
}
sub TimeToNum {
## doesn't work


Same deal -- pick up your argument first:

$_=shift;
 
G

Glenn Jackman

$today=`date`;
($weekday, $month, $day, $time, $junk) = split(' ', $today, 5);
$daynum = DayToNum( $day );
$timenum = TimeToNum( $time );

## 1 -> 01
print "\$daynum\( $day \) = $daynum \n";
## 12:16:56 -> 121656
print "\$timenum\( $time \) = $timenum \n";

my ($seconds, $minutes, $hours, $day) = (localtime)[0..3];
my $daynum = sprintf "%02d", $day;
my $timenum = sprintf "%02d%02d%02d", $hours, $minutes, $seconds;
 
E

Eric J. Roode

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

sub DayToNum {
## doesn't work
if ( length lt 2 ) { $_ = "0" . "$_"; }
## doesn't work
# if (/^1$/) { return "01"; }
# elsif (/^2$/) { return "02"; }
# elsif (/^3$/) { return "03"; }
# elsif (/^4$/) { return "04"; }
# elsif (/^5$/) { return "05"; }
# elsif (/^6$/) { return "06"; }
# elsif (/^7$/) { return "07"; }
# elsif (/^8$/) { return "08"; }
# elsif (/^9$/) { return "09"; }
# else { return "$_"; }
}
sub TimeToNum {
## doesn't work
s/://g;
## doesn't work
# $_ =~ s/://g;
## works...
# $timenum = $time;
# $timenum=~ s/://g;
}

Your main confusion seems to be with $_. In a subroutine, the argument
passed does not automatically go into $_. If you want it there, you have
to put it there with a line such as:

local $_ = shift;

There is also a somewhat nicer way to format a number with a leading
zero; use sprintf:

$num_with_leading_zero = sprintf '%02d', $num;

Also, you may want to look into my Time::Format module for doing all
sorts of everyday time/date formatting for display.

- --
Eric
$_ = reverse sort $ /. r , qw p ekca lre uJ reh
ts p , map $ _. $ " , qw e p h tona e and print

-----BEGIN PGP SIGNATURE-----
Version: PGPfreeware 7.0.3 for non-commercial use <http://www.pgp.com>

iQA/AwUBP6WPQWPeouIeTNHoEQI4iQCfS1VJ/vVbOmvkQMPfXGsBrwPc2nIAoJL1
kRpvgZ6oo/vOBSha2gH5YYGE
=qXTi
-----END PGP SIGNATURE-----
 
T

Tintin

I couldn't find the solution to this on google, so... There must be
some way to write two simple functions to convert a single digit date
to a two digit date and strip the ":" characters from time.

Thanks in advance,
Walter

#!perl
$today=`date`;
($weekday, $month, $day, $time, $junk) = split(' ', $today, 5);
$daynum = DayToNum( $day );
$timenum = TimeToNum( $time );

## 1 -> 01
print "\$daynum\( $day \) = $daynum \n";
## 12:16:56 -> 121656
print "\$timenum\( $time \) = $timenum \n";

sub DayToNum {
## doesn't work
if ( length lt 2 ) { $_ = "0" . "$_"; }
## doesn't work
# if (/^1$/) { return "01"; }
# elsif (/^2$/) { return "02"; }
# elsif (/^3$/) { return "03"; }
# elsif (/^4$/) { return "04"; }
# elsif (/^5$/) { return "05"; }
# elsif (/^6$/) { return "06"; }
# elsif (/^7$/) { return "07"; }
# elsif (/^8$/) { return "08"; }
# elsif (/^9$/) { return "09"; }
# else { return "$_"; }
}
sub TimeToNum {
## doesn't work
s/://g;
## doesn't work
# $_ =~ s/://g;
## works...
# $timenum = $time;
# $timenum=~ s/://g;
}

Holy Moly!! Perl aint that cumbersome.

You'll find this code a little shorter and more portable :)

#!/usr/bin/perl
use POSIX;
print strftime("Day: %d\n",localtime);
print strftime("Time: %H%M%S\n",localtime);
 
T

Tore Aursand


use strict;
use warnings;
$today=`date`;
($weekday, $month, $day, $time, $junk) = split(' ', $today, 5);

No need for a system call here. Just to this:

my ($sec, $min, $hour, $day, $month, $year) = (localtime)[0..5];
$year += 1900;
$month++;

perldoc -f localtime
$daynum = DayToNum( $day );
$timenum = TimeToNum( $time );

Those sub-routines was horrible. You might want to look into these:

perldoc -f printf
perldoc -f sprintf

Here's and example to print out the current date (from the code above):

printf("%4d-%02d%02d %02d:%02d:%02d", $year, $month, $day, $hour, $min,
$sec);
 
G

Guest

Eric J. Roode said:
Your main confusion seems to be with $_. In a subroutine, the argument
passed does not automatically go into $_. If you want it there, you have
to put it there with a line such as:

local $_ = shift;

Thanks Eric. I must be getting overly object-centric to have presumed $_
would be local and default to the sub's ARGV[0].

Walt
 
G

Guest

Bob Walton said:
You might consider using Perl's builtin localtime()

Thanks Bob. Though I should have posted a better example. What's
being parsed is log files, specifically the datestamp, for sorting.
Also need the local timezone i.e, MST, and can't, apparently, get it
from localtime().

Still haven't figured out TimeToNum() though. Given $time = "12:34:56";

sub TimeToNum {
$_ = shift;
s/://g;
}
TimeToNum($time)

returns "2" whereas

$time =~ s/://g;

returns the expected "123456".

Walt
 
G

Gunnar Hjalmarsson

Still haven't figured out TimeToNum() though.
Given $time = "12:34:56";

sub TimeToNum {
$_ = shift;
s/://g;
}
TimeToNum($time)

returns "2"

Yes it does. And if you wonder why, you'd better study the
documentation for Perl subroutines:

perldoc perlsub

or

http://www.perldoc.com/perl5.8.0/pod/perlsub.html

"The return value of a subroutine is the value of the last expression
evaluated."

You may want

sub TimeToNum {
$_ = shift;
s/://g;
return $_;
}
 
G

Gunnar Hjalmarsson

B

Ben Morrow

Eric J. Roode said:
Your main confusion seems to be with $_. In a subroutine, the argument
passed does not automatically go into $_. If you want it there, you have
to put it there with a line such as:

local $_ = shift;

Thanks Eric. I must be getting overly object-centric to have presumed $_
would be local and default to the sub's ARGV[0].

....Perl 6... :)

Ben
 
B

Bob Walton

Thanks Eric. I must be getting overly object-centric to have presumed $_
would be local and default to the sub's ARGV[0].


What is a "sub's ARGV[0]"??? Perhaps you mean the sub's @_ or perhaps
$_[0] ?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,141
Messages
2,570,817
Members
47,366
Latest member
IanCulpepp

Latest Threads

Top