Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:
Hi Monks!
I am trying to fix some display issues with dates, but for some reason I can't
figure it out why my code isn't working on today's date, here is what I have, I
just can't see where the problem is, and why today's date is matching on L1,
since I have to digits starting the first part of the date value, here is the
code :
#my $date = "$mon/$mday/$year";
my $date = "10/13/2006";
if ($date=~/(\d{1})\/(\d{2})\/(\d{4})/){
$date="0".$1."\/".$2."\/".$3;
print "<br>L1 - $date<br>";
}elsif($date=~/(\d{2})\/(\d{1})\/(\d{4})/)
{
$date=$1."\/0".$2."\/".$3;
print "<br>L2 - $date<br>";
}else{
$date=~/(\d{1})\/(\d{1})\/(\d{4})/;
$date="0".$1."\/0".$2."\/".$3;
}
Thanks for the Help!!!
formatting cleaned up by GrandFather
Re: Matching Date
by blazar (Canon) on Oct 13, 2006 at 14:36 UTC
|
I am trying to fix some display issues with dates, but for some reason I can't figure it out why my code isn't working on today's date, here is what I have, I just can't see where the problem is, and why today's date is matching on L1, since I have to digits starting the first part of the date value,
First, I had some difficulties reading your code. Thus I reformatted it, with no substantial modification:
my $date = "10/13/2006";
if ($date=~/(\d{1})\/(\d{2})\/(\d{4})/) {
$date="0".$1."\/".$2."\/".$3;
print "<br>L1 - $date<br>";
} elsif ($date=~/(\d{2})\/(\d{1})\/(\d{4})/) {
$date=$1."\/0".$2."\/".$3;
print "<br>L2 - $date<br>";
} else {
$date=~/(\d{1})\/(\d{1})\/(\d{4})/;
$date="0".$1."\/0".$2."\/".$3;
# no print here?!?
}
So it seems that you want to "normalize" month and day to two digits. Then I would switch logic altogether:
my $date = "10/13/2006";
my ($m,$d,$y)=split m(/), $date;
$date=join '/', (map sprintf('%02d', $_), $m, $d), $y;
Update: I don't have the slightest idea of what I was thinking of, but I was reinventing the wheel myself, using awkward logic to implement something that sprintf offers out of the box in the first place:
my $date = "10/13/2006";
$date=sprintf '%02d/%02d/%d', split m(/), $date;
Of course this does not do full validation of the initial $date but that's something you can add easily once you have $m, $d and $y. So I don't know why your code "doesn't work" for today's date, but the lesson is, I hope: do not reinvent the wheel! | [reply] [d/l] [select] |
|
This is an alternate version of blazar's solution, which may be slightly easier for new Perl programmers (and possibly future maintenance programmers) to understand:
#my $date = "$mon/$mday/$year";
my $date = "10/13/2006";
my ($mon,$mday,$year) = split('/',$date);
$mon = sprintf("%02d",$mon);
$mday = sprintf("%02d",$mday);
$date = "$mon/$mday/$year";
Also, I'd like to point the OP to Date::Calc and Date::Format.
---
It's all fine and dandy until someone has to look at the code.
| [reply] [d/l] |
Re: Matching Date
by Hue-Bond (Priest) on Oct 13, 2006 at 14:41 UTC
|
I just can't see where the problem is, and why today's date is matching on L1
Why shouldn't it? It has a number followed by a slash and then 2 numbers... Maybe you want to anchor the regex to the beginning and end of the string?:
my @dates = qw| 10/13/2006 1/13/2006 10/1/2006 1/1/2006 |;
foreach my $date (@dates) {
if ($date =~ m|^(\d{1,2}) / (\d{1,2}) / (\d{4})$|x) { ## <-- anc
+horing
$date = sprintf "%02d/%02d/%04d", $1, $2, $3;
}
print "result: <$date>\n";
}
__END__
result: <10/13/2006>
result: <01/13/2006>
result: <10/01/2006>
result: <01/01/2006>
Update: Typo fix.
| [reply] [d/l] |
Re: Matching Date
by johngg (Canon) on Oct 13, 2006 at 15:03 UTC
|
Other Monks have provided solutions to your problem but your OP and some of the replies would, IMHO, be more readable given an alternative choice of regular expression delimiter. Instead of
$date =~ /(\d\d?)\/(\d\d?)\/(\d{4})/;
I would prefer
$date =~ m{(\d\d?)/(\d\d?)/(\d{4})};
to avoid having to keep escaping the date separators. Cheers, JohnGG | [reply] [d/l] [select] |
|
if ($date=~/^(\d{1})\/(\d{2})\/(\d{4})$/g){
+ $date="0".$1."\/".$2."\/".$3;
+ print "<br>L1 - $date<br>";
}elsif($date=~/^(\d{2})\/(\d{1})\/(\d{4})/g){
+ $date=$1."\/0".$2."\/".$3;
+
+ print "<br>L2 - $date<br>";
}elsif($date=~/^(\d{1})\/(\d{1})\/(\d{4})/g){
+ $date="0".$1."\/0".$2."\/".$3;
}else{
$date=$date;
+
}
| [reply] [d/l] |
Re: Matching Date
by RobPayne (Chaplain) on Oct 13, 2006 at 14:42 UTC
|
It's not clear exactly what you wanted to happen in the above, but your first pattern was matching because you didn't tell it the pattern needed to start with the first character. Without the ^ that I added, to the beginning of each regex, perl would begin the match wherever it could in the string. You may also want to finish the regex off with a $ so you only match when the entire line matches, depending upon you you are getting your $mon/$mday/$year, with an else for something that really isn't a good match.
#my $date = "$mon/$mday/$year";
my $date = "10/13/2006";
if ($date=~/^(\d{1})\/(\d{2})\/(\d{4})/)
{
$date="0".$1."\/".$2."\/".$3;
print "<br>L1 - $date<br>\n";
}
elsif($date=~/^(\d{2})\/(\d{1})\/(\d{4})/)
{
$date=$1."\/0".$2."\/".$3;
print "<br>L2 - $date<br>\n";
}
elsif($date=~/^(\d{2})\/(\d{2})\/(\d{4})/)
{
$date=$1."\/0".$2."\/".$3;
print "<br>L3 - $date<br>\n";
}
else{
$date=~/^(\d{1})\/(\d{1})\/(\d{4})/;
$date="0".$1."\/0".$2."\/".$3;
print "<br>L4 - $date</br>\n";
}
That prints 'L3 - 10/13/2006' between breaks. | [reply] [d/l] |
Re: Matching Date
by Skeeve (Parson) on Oct 13, 2006 at 14:43 UTC
|
$date=~/(\d{1})\/(\d{2})\/(\d{4})/ This matches 1 digit for month (= "0") and not 2. Better would be: $date=~/(\d\d?)\/(\d\d?)\/(\d{4})/
or, if you want curly braces: $date=~/(\d{1,2})\/(\d{1,2})\/(\d{4})/
or, if you like to check more: $date=~/(0?[1-9]|1[0-2])\/(0?[0-9]|[12]\d|3[01])\/(\d{4})/
s$$([},&%#}/&/]+}%&{})*;#$&&s&&$^X.($'^"%]=\&(|?*{%
+.+=%;.#_}\&"^"-+%*).}%:##%}={~=~:.")&e&&s""`$''`"e
| [reply] [d/l] [select] |
Re: Matching Date
by fenLisesi (Priest) on Oct 13, 2006 at 17:24 UTC
|
01/02/2006 => (01, 02, 2006) => (01, 02, 2006)
1/2/2006 => ( 1, 2, 2006) => (01, 02, 2006)
11/22/2006 => (11, 22, 2006) => (11, 22, 2006)
12/1/2006 => (12, 1, 2006) => (12, 01, 2006)
13/1/2006 => No match
2/35/2006 => No match
1/2/06 => No match
Hope this helps.
Update: Added <readmore> | [reply] [d/l] [select] |
|
|