lyapunov has asked for the wisdom of the Perl Monks concerning the following question:
Dear PerlMonks, one of the things that I have gotten religion about, particularly after reading "Effective Perl Programming" by Hall, McAdams, and foy, is using strict.
Recently, I am trying to build a few generalized subroutines for tasks that I have done over and over, with the eventual goal of building my own module. The goal of making these routines as reusable as possible, has led me to, at least hopefully, make better design desisions.
As a great deal of my work involves system administration. I created the following routine to provide a generic interface for returning a date string from localtime for use in archiving logs files and the like. The idea is to call the subroutine with two arguments, the first being the format of the information that you want returned e.g. YYYYMMDD and the second argument is the offset from current time. Negative numbers take you back in time, positive numbers will generate a return from a future date.
As I have stated, I am writing all of my code to be strict compliant, but one of my peer's reviewed my code and suggested that making the second argument of the time_offset to be optional, so in the case that it is omitted, zero offset is assumed. I have done a fair amount of research, but have gone nowhere quickly.
I currently have the prototype as return_time($ $) but if I call it without the second argument, it bails. Is what I am trying to do possible, worthwhile> Would any of you mind leading me to an enlightned path?
FYI I try to do a reasonable job of documenting my code, but if you have any questions or concerns that are not addressed, please let me know. Also, having been on the receiving end of working on other peoples code, my overriding philosophy that I have adopted while writing code is taken from Conway's "Perl Best Practices" - "Always code as if the the guy who ends up maintaining your code will be a violent psychopath who knows where you live." It may not be as idiomatic and compact as possible, but I hope that it is at least not amateurish.
As always, any other design or critiques are welcomed. I am here to learn after all. Again, many thanks for your help and insight.
############################### ############################### # # subroutine_name: return_time # # Purpose: To provide a generic interface for extracting human readabl +e # values in an arbritrary order from epoch time. # # # # Arguments: This subroutine is designed to take two arguments: # # First required The format of the time string you want returned. # Second optional The signed offset from the current time in second +s. # To go back in time use a negative number. # To go forward use a positive number. # # # # Limitations: none # # # # Dependencies: perl 5.010 # pad_with_zeroes # # # # Description: After having to deal with stripping specific time # formats out of localtime on a program-by-program basis this is an # attempt to remedy the situation. # # To use this subroutine call it with a string where the values you wa +nt # out are in the order you want them out each specific piece of # information needs to be separated by a colon. # # Here is the reference manual; # YYYY the four digit year. # YY the last two digits of the year. # DD is the double digit day 01-31 # MMM 3 letter alpha name for the month in ALL CAPS # Mmm 3 letter alpha name for the month with just the 1st letter + CAPPED # MM The number of the month 01 for Jan - 12 for Dec # julian the julian day of the year. # hh hours # mm minutes # ss seconds # Ddd the 3 alpha name of the weekday 1st letter CAPPED # DDD the 3 alpha name of the weekday ALL CAPS # # Recall that there are 86400 seconds in a day. # # To get the the YYYYMMDD for yesterday call # return_time("YYYY:MM:DD", -86400); # # To get the YYYY:julian for next week call # return_time("YYYY:julian", 7*86400); # # # # Changelog: # Date Engineer DR Change Description # 28 Jul 11 Mike K Program Creation # # ############################### ############################### sub return_time ($ $) { # # setup requirements, eat your greens # use Time::Local; use 5.010; # # Data Structures needed for quick conversion of # numeric values return by localtime into useable # formats; # my %month_to_num = ("0","01", "1","02", "2","03", "3","04", "4","05", "5","06", "6","07", "7","08", "8","09", "9","10", "10","11", "11","12"); my %month_to_name = ("0","Jan", "1","Feb", "2","Mar", "3","Apr", "4","May", "5","Jun", "6","Jul", "7","Aug", "8","Sep", "9","Oct", "10","Nov", "11","Dec"); my %day_to_alphaday = ("0", "Sun", "1","Mon", "2","Tue", "3","Wed", "4","Thu", "5","Fri", "6","Sat"); # # Variable declarations # my $input_string; my @time_outputs; my $offset_from_current_time; my $output_time_string; my $time; my $temp; my $cur_day_sec; my $cur_day_min; my $cur_day_hour; my $cur_day_mday; my $cur_day_mon; my $cur_day_year; my $cur_day_wday; my $cur_day_yday; my $cur_day_isdst; # # Grab the input string and split it into an array. # $input_string=shift; $offset_from_current_time=shift; # # The code that I want to handle the case of the offset being zero # in case the second argument is not included will go here. # # Basically if defined use that, else $offset_from_current_time=0; # # @time_outputs=split ":", $input_string; # # Extract values into assorted variable from localtime # ($cur_day_sec, $cur_day_min, $cur_day_hour, $cur_day_mday, $cur_day +_mon, $cur_day_year, $cur_day_wday, $cur_day_yday, $cur_day_isdst)=localtime(time()+$offset_from_current_time); # # The return strings will be formed in the order given # The following basically works like a case statement in # shell. # # the variable temp is used so as not to modify the original data. # foreach $time (@time_outputs) { given ($time) { when ('YYYY') { $temp=$cur_day_year+1900; $output_time_string=$output_time_string."$temp"; } when ('YY') { # # Barewords in strict are not allowed hence # the qw in front of the unpack arguments. # $temp=$cur_day_year+1900; (my $d1, my $d2, my $d3, my $d4)=unpack qw(A1A1A1A1),$temp +; $temp=$d3.$d4; $output_time_string=$output_time_string."$temp"; } when ('DD') { $output_time_string=$output_time_string."$cur_day_mday"; } when ('julian') { $temp=pad_with_zeroes($cur_day_yday+1,3); $output_time_string=$output_time_string."$temp"; } when ('MMM') { $temp=$month_to_name{"$cur_day_mon"}; $temp=~tr/a-z/A-Z/; $output_time_string=$output_time_string."$temp"; } when ('Mmm') { $temp=$month_to_name{"$cur_day_mon"}; $output_time_string=$output_time_string."$temp"; } when ('MM') { $temp=$month_to_num{"$cur_day_mon"}; $output_time_string=$output_time_string."$temp"; } when ('Ddd') { $temp=$day_to_alphaday{"$cur_day_wday"}; $output_time_string=$output_time_string."$temp"; } when ('DDD') { $temp=$day_to_alphaday{"$cur_day_wday"}; $temp=~tr/a-z/A-Z/; $output_time_string=$output_time_string."$temp"; } # # For hours minutes and seconds localtime does not return # zero padded values. These are all padded to two digit # lengths to remove ambiguity e.g. would 1411 mean # 140101 or 141100 and so on. # when ('hh') { $temp=pad_with_zeroes($cur_day_hour,2); $output_time_string=$output_time_string."$temp"; } when ('mm') { $temp=pad_with_zeroes($cur_day_min,2); $output_time_string=$output_time_string."$temp"; } when ('ss') { $temp=pad_with_zeroes($cur_day_sec,2); $output_time_string=$output_time_string."$temp"; } } } # # Return the string # return $output_time_string; } ################################ ################################ # # subroutine_name: pad_with_zeroes # # Purpose: This routine takes a single number and pads and arbitrary +amount of zeroes in front of it. # # Limitations: none # # Dependencies: # # Description: This subroutine requires two arguments to be passed to +it. The first is the # the value you want padded with prepending zeroes. The second is the +the length that you # want the final string to be. If the value you want padded is greater + than the pad length # nothing will change, e.g. # # pad_with_zeroes(1,2) will return 01 # pad_with_zeroes(1,3) will return 001 # pad_with_zeroes(1000,1) will return 1000 # # # Changelog: # Date Engineer DR Change Description # 06 Jul 11 Mike Kmetz N/A Program Creation # # ############################### ############################### sub pad_with_zeroes ($ $){ # # Variable declarations # my ($value, $pad_length); # # Load the values and do the work # $value=shift; $pad_length=shift; # # We test to see if the length of the value is shorter # than the length of the zero padding desired # If it is the zeroes are prepended. If not the # orginal value is returned. if (length($value)<$pad_length ) { do { $value="0".$value; } until (length($value) eq $pad_length); } # # Return the value. # return $value; }
|
---|