chexmix has asked for the wisdom of the Perl Monks concerning the following question:
As loath as I am to expose the true weakness of my brains in this austere, sacred realm, well, I'm at a point in my path to enlightenment where I should probably do just that. And so I am going to post an example of the kind of "CCNTwBnOGbSWDRGIY" (Crud Code Nailed Together with Boogers 'n' Other Goo by Someone Who Doesn't Really Get It Yet) I am so far capable of, for your delectation and my edification.
The genesis of the eldritch thing below is that I need to pass start and stop time values and a "pad" value (in seconds) for a database query. The pad value will be subtracted from the start value and added to the stop value to yield a time range which will be "pad value larger" on either end than the stop and start times indicate.
I had considered trying to let Sybase handle all the time-stuff but then found the "timelocal" function in Time::Local and its inverse, the builtin localtime, and thought, well, let's see if I can make it work in Perl.
The posted code only takes a single time value and has a 300 second padding hardcoded in. This was for simplicity's sake. It seems to work (It chokes though on a year like 2202), but wow, is it ugly. In particular I am sure there is something wrong with the way I am getting a properly formatted string back out of localtime. There is a lot of stuff that feels as though it should be pulled into subroutines and made more elegant ...
I invite and welcome comments, suggestions on how to do this better. I know it's pretty rugose and squamous at this point :^) It felt like something that should have been easy and wasn't as easy as it looked (especially when I found I couldn't use split properly on the string returned by localtime). But I am probably missing a lot of things.
#!/usr/bin/perl use warnings; use strict; use Time::Local; # Get timestamp input from user print "Enter a timestamp in mm/dd/yyyy hh:mm:ss format: "; chomp(my $stamp = <STDIN>); # Split out various fields for timelocal my($date, $time) = split / /, $stamp; my($month, $day, $year) = split /\//, $date; my($hour, $minute, $second) = split /:/, $time; # Both timelocal and localtime understand month as in 0 - 11 range $month -= 1; # Get time value in seconds since Epoch with timelocal my $now = timelocal($second,$minute,$hour,$day,$month,$year); # Add padding (this will become interactive) my $paddednow = $now + 300; # Get sensible timestamp back out with localtime my $answer = localtime($paddednow); # Convert result to array for laborious processing of fields my @Answer = split //, $answer; my $Amon = $Answer[4].$Answer[5].$Answer[6]; my $Aday = $Answer[8].$Answer[9]; my $Atime = $Answer[11].$Answer[12].$Answer[13].$Answer[14].$Answer[15 +].$Answer[16].$Answer[17].$Answer[18]; my $Ayear = $Answer[20].$Answer[21].$Answer[22].$Answer[23]; # Declare hash for conversion of monthname values my %monthy = ( "Jan" => "01", "Feb" => "02", "Mar" => "03", "Apr" => "04", "May" => "05", "Jun" => "06", "Jul" => "07", "Aug" => "08", "Sep" => "09", "Oct" => "10", "Nov" => "11", "Dec" => "12" ); # Handle leading zero issue with day of month my %daything = ( " 1" => "01", " 2" => "02", " 3" => "03", " 4" => "04", " 5" => "05", " 6" => "06", " 7" => "07", " 8" => "08", " 9" => "09" ); my $Amonth = $monthy{$Amon}; my $Arealday; if ($Aday < 10) { $Arealday = $daything{$Aday}; } else { $Arealday = $Aday } # Cobble together result in same format as input my $Adate = join "/", $Amonth, $Arealday, $Ayear; my $realanswer = join " ", $Adate, $Atime; print "$stamp + 5 minutes is $realanswer\n";
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Attack of the killer timestamps
by jwkrahn (Abbot) on Mar 20, 2008 at 20:43 UTC | |
by chexmix (Hermit) on Mar 20, 2008 at 20:51 UTC | |
by mr_mischief (Monsignor) on Mar 20, 2008 at 22:11 UTC | |
by chexmix (Hermit) on Mar 21, 2008 at 13:35 UTC | |
by holli (Abbot) on Mar 20, 2008 at 22:34 UTC | |
|
Re: Attack of the killer timestamps
by kyle (Abbot) on Mar 20, 2008 at 20:39 UTC | |
by chexmix (Hermit) on Mar 20, 2008 at 20:42 UTC | |
|
Re: Attack of the killer timestamps
by apl (Monsignor) on Mar 20, 2008 at 20:31 UTC | |
|
Re: Attack of the killer timestamps
by dwm042 (Priest) on Mar 20, 2008 at 20:29 UTC | |
|
Re: Attack of the killer timestamps
by mpeppler (Vicar) on Mar 21, 2008 at 17:12 UTC | |
by chexmix (Hermit) on Mar 21, 2008 at 18:20 UTC | |
| A reply falls below the community's threshold of quality. You may see it by logging in. |