General Purpose Date Script


 
Thread Tools Search this Thread
Top Forums UNIX for Beginners Questions & Answers General Purpose Date Script
# 15  
Old 05-05-2016
A few bugfixes and improvements, such as the ability to ask it for "last week". It removes a lot of undefined behavior that happened whenever it had partial arguments. Base time and offsets are now calculated in different loops, and you can specify more than one offset now, like "last week + 5 hours - 3 minutes"

Code:
#!/usr/bin/perl

use POSIX;
use strict;
use warnings;

my $cmdstr="%Y-%m-%d %H:%M:%S";		# see strftime
my ($input, $arg, $sign, $ref,$offset,$quiet,$n)=("", undef, 0, time,0,0,0);
# $lt[SEC] is seconds, etc.  See perldoc -f localtime
use constant {	SEC=>0,	MIN=>1,	HOUR=>2,DAY=>3,	MON=>4,	YEAR=>5,WDAY=>6 };
# Titles for localtime() array elements
my @title=("Seconds","Minutes","Hours","Day","Month","Year","Weekday");
# Times stored in the format of 'perldoc -f localtime'.
# In the case of @changed, only elements that were altered in @lt are 
# set,other values are undefined.
my (@lt, @changed);
# Lookups for mon/tues/wed jan/feb/mar names into day and month numbers
my (%month, %days);
my %mult=("second" => 1, "minute" => 60, "hour" => 60*60, "day" => 60*60*24,
	"week"=>60*60*24*7, "year" => 31536000 );
# Alter a value in @lt and copy that value into the same index of @changed
sub set {
	my ($i,$v)=(shift,shift);
	$lt[$i]=$changed[$i]=$v;
}

# Takes an hour in AM, returns a number in 24-hour time
sub am { if($_[0] == 12) { return($_[0] - 12); } return($_[0]); }
# Takes an hour in PM, returns an hour in 24-hour time
sub pm { if($_[0] >= 1) { return($_[0] + 12); } return($_[0]); }

# loadhash(\%hash, "A;B", "a;b")
# sets $hash{A}=0, $hash{B}=1, $hash{a}=0, $hash{b}=1
sub loadhash {
        my ($h,$n)=(shift,0);
	foreach(@_)	{
		$n=0; foreach(split('[;\n]', lc($_))) { ${$h}{$_}=$n++; }
	}
}

# Parse commandline arguments
while(defined($arg=shift)) {
        if($arg =~ /^--date=/)  {       $input=substr($arg, 7);         }
        elsif($arg =~/^\+/)     {       $cmdstr=substr($arg,1);         }
	elsif($arg eq "-q")	{	$quiet=1;			}
        elsif($arg eq "-d")   {       $input=shift;                   }
        elsif(($arg eq "-r") || ($arg =~ /^--reference=(.*)$/))
	{
		if(defined($1))	{ $arg=$1; }
		else		{ $arg=shift; }
	        my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
        	       $atime,$mtime,$ctime,$blksize,$blocks)
	               = stat($arg);

	        defined($dev) || die("No such file $arg");

		$ref=$mtime;
	}
        elsif($arg =~/^-h|--help|--version$/) {
                print STDERR <<"EOT";
date.pl v0.0.8, Tyler Montbriand, 2016.  Free PERL date calc/converter.
 -d "time string"       string like "YYYYMMDD", "YYYY/MM/DD",
                        "HHMMSS", "HH:MM:SS", "\@epoch", "- 3 days",
			"Mar 3 2016 1:16:09 AM", 
                        etc.  You can string them together, like
                        "\@1343322750 - 3 days".

 -r /path/to/file       Show mtime of the given file, not current time.

 +"formatstring"        Give strftime this format string instead of the
                        default "%Y-%m-%d %H:%M:%S".  See 'man strftime'

 -q			date.pl warns you when given conflicting
			information, i.e. feb 29 not on a leap year.
			It also warns you when input isn't understood.
			-q suppesses this.
Examples:
date.pl                         # current time in YYYY-MM-DD HH:MM:SS
TZ="UTC" ./date.pl              # Use an alternate time zone
date.pl +"%a %b %d %Y %r"       # Like Thu Jan 16 2014 12:58:59 PM
date.pl -d "+ 3 days"           # Current time plus three days
date.pl -d "\@1343322750"       # exact time in epoch seconds
date.pl -d "2013/01/02 12:00:00"# exact time in YYYYMMDD HHMMSS
date.pl -d "9am"                # Today at 9am
date.pl -d "last week + 5 minutes"
date.pl -r /etc/passwd          # display mtime of /etc/passwd
date.pl -r /etc/passwd -d "12:00:00" # date of /etc/passwd, time of noon
EOT
                exit(1);
        }
        else {       die("unknown argument $arg, try --help");   }
}

# Load hashes full of day and month names

#loadhash(\%month, `locale mon`, `locale abmon`);
loadhash(\%month, "January;February;March;April;May;June;July;August;September;October;November;December",
	"Jan;Feb;Mar;Apr;May;Jun;Jul;Aug;Sep;Oct;Nov;Dec");
#loadhash(\%days, `locale day`, `locale abday`);
loadhash(\%days, "Sunday;Monday;Tuesday;Wednesday;Thursday;Friday;Saturday",
	"Sun;Mon;Tues;Wed;Thurs;Fri;Sat");

@lt=localtime($ref);

# Lowercase input so we can look up tokens like 'monday' in hashes
$input=lc($input);
# Separate strings and numbers into their own tokens, like "9am" => "9 am"
# : still belongs with numbers for HH:MM:SS etc.
$input =~ s/([0-9:])([a-z])/$1 $2/g;
$input =~ s/([a-z])([0-9:])/$1 $2/g;

# Split input on whitespace and commas and jam back into ARGV
unshift(@ARGV, split(/[ \r\n\t,]+/, $input));

while(!$sign && defined($arg=shift))
{
        # Need to split +1 into +, 1
        if($arg =~ /^[+]/) {
		$sign=1;
		if(length($arg) > 1) { unshift(@ARGV, substr($arg,1)); }
		next;
	}
        elsif($arg =~ /^-/) {
		$sign=-1;
		if(length($arg) > 1) { unshift(@ARGV, substr($arg,1)); }
		next;
	}

	if($arg eq "plus")	{	$sign=1;	next;	}
	if($arg eq "minus")	{	$sign=-1;	next;	}

        if(length($arg) == 0){ next } # Empty string?  Ignore

        ################## DATE FORMAT DETECTION ########################

        # Dates like "Jan" "17"
	if(exists($month{$arg}))
	{
		set(MON, $month{$arg});
		if(($#ARGV >= 0) && ($ARGV[0] =~ /^[0-9]+$/))
		{
			set(DAY, $ARGV[0] + 0);
			shift;
		}
		next;
	}

	# mon/monday/etc
	if(exists($days{$arg})) {
		set(WDAY, $days{$arg} );

		# If it's followed by a numeral, i.e. Monday 7,
		# the numeral is the day of the month
		if(($#ARGV >= 0) && ($ARGV[0] =~ /^[0-9]+$/))
		{ set(DAY, $ARGV[0] + 0); shift; }

		next;
	}

	# a bare 4-digit number beginning with 19 or 20 is probably a year
	if($arg =~ /^(19[0-9][0-9])|^(2[0-9][0-9][0-9])$/)
	{	set(YEAR, $arg - 1900);	next;	}

        # @1234 means seconds in epoch time
        if($arg =~ /^@([0-9]+)$/)      {
		@lt=localtime($1+0);
		# Date has been replaced, prev changes are now irrelevant
		for($n=0; $n<8; $n++) { $changed[$n]=undef; }
		next;
	}

        # Checks for YYYYMMDD or YYYY/MM/DD time
        if(($arg =~ /^([0-9]{4})([\/-])([0-9]{1,2})\2([0-9]{1,2})$/) ||
		($arg =~ /^([0-9]{4})()([0-9]{2})([0-9]{2})$/))
        {
		set(YEAR, $1-1900); set(MON, $3-1); set(DAY, $4+0);

		# Set time variables which haven't been set already
		if(!defined($changed[HOUR]))
		{ set(SEC,0); set(MIN,0); set(HOUR,0); }

                next;
        }

        # HH:MM:SS times.  Sub-second times are allowed but ignored
        if($arg =~ /([0-2]?[0-9]):([0-5][0-9])(:([0-5][0-9])(.[0-9]+)?)?$/)
        {
		if(defined($4)) { set(SEC, $4+0); }
		else		{ set(SEC, 0); }

		set(MIN, $2+0);	set(HOUR, $1+0);

		# Handle time with PM in it
		if($#ARGV < 0) { }
		elsif($ARGV[0] eq "pm")  { set(HOUR, pm($lt[HOUR])); shift; }
		elsif($ARGV[0] eq "am")  { set(HOUR, am($lt[HOUR])); shift; }
                next;
        }

        # Times like 9 AM
        if(($arg =~ /^([0-9]+)$/) && ($#ARGV>=0) && ($ARGV[0] =~ /^(am|pm)$/)) {
		$arg=$arg + 0;

		set(SEC, 0); set(MIN,0); set(HOUR, $arg);
		if($ARGV[0] eq "am") { set(HOUR, am($lt[HOUR])); }
		else                 { set(HOUR, pm($lt[HOUR])); }
		shift;
		next;
	}

	# Redundant, but whatever
        if($arg =~ /^now$/)  {
		@lt=localtime(time);
		# Date has been replaced, prev changes are now irrelevant
		for($n=0; $n<8; $n++) { $changed[$n]=undef; }
		next
	}

	# last second/minute/hour/week/year
	if($arg =~ /^(last)|(next)$/)
	{
		if(defined($1)) { $offset=-1; } else { $offset=1; }

		if($#ARGV < 0)
		{
			if(!$quiet)
			{	print STDERR "next what, exactly?\n"	}

			next;
		}

		$ARGV[0] =~ s/s$//;

		if(defined($mult{$ARGV[0]}))
		{
			@lt=localtime(time);
			# Date has been replaced, prev changes are now irrelevant
			for($n=0; $n<8; $n++) { $changed[$n]=undef; }
			$offset *= $mult{$ARGV[0]};
		}
		elsif($ARGV[0] eq "month")
		{
			$offset=0;
			$lt[MON] += $sign;

			if($lt[MON] >= 12) { $lt[YEAR]++; $lt[MON] -= 12; }
			if($lt[MON] < 0) { $lt[MON] += 12; $lt[YEAR] --; }

			set(MON, $lt[MON]);
			set(YEAR, $lt[YEAR]);
		}
		elsif(!$quiet)
		{
			print STDERR $ARGV[0]." not a valid option for next\n";
		}

		shift;
		next;
	}

        if(! $quiet) {
                print STDERR "Unknown argument $arg\n";
        }
}

# If a + / - sign was found, process the next arguments as the offset
while($sign && defined($arg=shift))
{
	# Might find another sign.
        if($arg =~ /^[+]/) {
		$sign=1;
		if(length($arg) > 1) { unshift(@ARGV, substr($arg,1)); }
		next;
	}
        elsif($arg =~ /^-/) {
		$sign=-1;
		if(length($arg) > 1) { unshift(@ARGV, substr($arg,1)); }
		next;
	}

	if($arg eq "plus")	{	$sign=1;	next;	}
	if($arg eq "minus")	{	$sign=-1;	next;	}

	# A number followed by a type, "9" "years"
	$arg =~ s/s$//;
	if(($arg =~ /^[0-9]+$/) && ($#ARGV >= 0))
	{
		# second/minute/hour/day/week/year are just multiplication
		$ARGV[0] =~ s/s$//g;

		if(defined($mult{$ARGV[0]}))
		{
			$offset += $mult{$ARGV[0]} * $arg * $sign;
			shift;
		}
		elsif($ARGV[0] =~ /months?/)	# months means counting
		{
			while($arg >= 12)
			{
				$arg -= 12;
				$offset += $sign * $mult{"year"};
			}

			$lt[MON] += $arg * $sign;
                        while($lt[MON] >= 12) { $lt[MON]-=12; $lt[YEAR]++; }
			while($lt[MON] < 0)  { $lt[MON]+=12; $lt[YEAR]--; }

			set(MON, $lt[MON]); set(YEAR, $lt[YEAR]);
			shift;
		}
		else
		{
			if(!$quiet) {
				print STDERR "Unknown element ".$ARGV[0]."\n";
			}
			shift;
		}

	}
}

# Convert the altered year, month, etc back into epoch time.
my $nref=mktime(@lt);
# Convert back into year, month, etc, to see if the input made sense.
my @san=localtime($nref);

for($n=0; $n<=6; $n++)
{
	if(($quiet == 0) && defined($changed[$n]) && ($changed[$n] != $san[$n]))
	{
		printf STDERR "%s changed, inconsistent input?", $title[$n];
		printf STDERR "\t%s in %s out\n", $changed[$n], $san[$n];
	}
}

# Print the calculated time plus offset
print strftime($cmdstr."\n", localtime($nref + ($offset)));
exit(0);


Last edited by Corona688; 05-05-2016 at 07:54 PM..
# 16  
Old 05-17-2016
Here it is trimmed down and made far less ugly, with some bits moved into subs, subs moved down out of the way, and processing is now far less of a kludge in general. This is the next "official" version.

Code:
#!/usr/bin/perl

use POSIX;
use strict;
use warnings;

my $cmdstr="%Y-%m-%d %H:%M:%S";		# see strftime
my ($input, $arg, $sign, $ref,$offset,$quiet,$n)=("", undef, 0, time,0,0,0);
# $lt[SEC] is seconds, etc.  See perldoc -f localtime
use constant {	SEC=>0,	MIN=>1,	HOUR=>2,DAY=>3,	MON=>4,	YEAR=>5,WDAY=>6 };
# Times stored in the format of 'perldoc -f localtime'.
# In the case of @changed, only elements that were altered in @lt are 
# set,other values are undefined.
my (@lt, @changed);
# Lookups for mon/tues/wed jan/feb/mar names into day and month numbers
my (%month, %days);
# Lookup table to convert 'year' into a number of seconds, etc
my %mult=("second" => 1, "seconds" => 1, "minute" => 60, "minutes" => 60,
	"hour" => 3600, "hours" => 3600, "day" => 86400, "days" => 86400,
	"week" => 604800, "weeks" => 604800,
	"year" => 31536000, "years" => 31536000 );

# Parse commandline arguments
while(defined($arg=shift)) {
        if($arg =~ /^--date=(.*)/)  {       $input=$1;                  }
        elsif($arg eq "-d")         {       $input=shift;               }
        elsif($arg =~/^\+(.*)/)     {       $cmdstr=$1;                 }
	elsif($arg eq "-q")	    {	    $quiet=1;		        }
        elsif(($arg eq "-r") || ($arg =~ /^--reference=(.*)$/))
	{
		if(defined($1))	{ $arg=$1; }
		else		{ $arg=shift; }
	        my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,
        	       $atime,$mtime,$ctime,$blksize,$blocks)
	               = stat($arg);

	        defined($dev) || die("No such file $arg");

		$ref=$mtime;
	}
        elsif($arg =~/^(-h|--help|--version)$/) {
                print STDERR <<"EOT";
date.pl v0.1.0, Tyler Montbriand, 2016.  Free PERL date calc/converter.
 -d "time string"       string like "YYYYMMDD", "YYYY/MM/DD",
                        "HHMMSS", "HH:MM:SS", "\@epoch", "- 3 days",
			"Mar 3 2016 1:16:09 AM", 
                        etc.  You can string them together, like
                        "\@1343322750 - 3 days".

 -r /path/to/file       Show mtime of the given file, not current time.

 +"formatstring"        Give strftime this format string instead of the
                        default "%Y-%m-%d %H:%M:%S".  See 'man strftime'

 -q			date.pl warns you when given conflicting
			information, i.e. feb 29 not on a leap year.
			It also warns you when input isn't understood.
			-q suppesses this.
Examples:
date.pl                         # current time in YYYY-MM-DD HH:MM:SS
TZ="UTC" ./date.pl              # Use an alternate time zone
date.pl +"%a %b %d %Y %r"       # Like Thu Jan 16 2014 12:58:59 PM
date.pl -d "+ 3 days"           # Current time plus three days
date.pl -d "\@1343322750"       # exact time in epoch seconds
date.pl -d "2013/01/02 12:00:00"# exact time in YYYYMMDD HHMMSS
date.pl -d "9am"                # Today at 9am
date.pl -d "last week + 5 minutes"
date.pl -r /etc/passwd          # display mtime of /etc/passwd
date.pl -r /etc/passwd -d "12:00:00" # date of /etc/passwd, time of noon
EOT
                exit(1);
        }
        else {       die("unknown argument $arg, try --help");   }
}

# Load hashes full of day and month names

#loadhash(\%month, `locale mon`, `locale abmon`);
loadhash(\%month, "January;February;March;April;May;June;July;August;September;October;November;December",
	"Jan;Feb;Mar;Apr;May;Jun;Jul;Aug;Sep;Oct;Nov;Dec");
#loadhash(\%days, `locale day`, `locale abday`);
loadhash(\%days, "Sunday;Monday;Tuesday;Wednesday;Thursday;Friday;Saturday",
	"Sun;Mon;Tues;Wed;Thurs;Fri;Sat");

@lt=localtime($ref);

# Lowercase input so 'tues', etc can be reliably found in tables
$input=lc($input); 
# Separate strings and numbers into their own tokens, like "9am" => "9 am"
# : still belongs with numbers for HH:MM:SS etc.
$input =~ s/([0-9:])([a-z])/$1 $2/g;
$input =~ s/([a-z])([0-9:])/$1 $2/g;
# Split +/- into their own tokens
$input =~ s/([+-])/ $1 /g;

# Split input on whitespace and commas and jam back into ARGV
unshift(@ARGV, split(/[ \r\n\t,]+/, $input));

while(defined($arg=shift))
{
        if(length($arg) == 0){ next; } # Empty string?  Ignore

	# Handle these in offset section
	if(($arg eq "+")||($arg eq "plus")||($arg eq "-")||($arg eq "minus"))
	{	unshift(@ARGV, $arg);	last;	}

        ################## DATE FORMAT DETECTION ########################

	if(exists($month{$arg})) # Dates like "Jan" "17"
	{
		set(MON, $month{$arg});
		if(($#ARGV >= 0) && ($ARGV[0] =~ /^[0-9]+$/))
		{	set(DAY, $ARGV[0] + 0);	shift;	}
		next;
	}

	if(exists($days{$arg}))	# mon/monday/etc
        {
		set(WDAY, $days{$arg} );

		# If it's followed by a numeral, i.e. Monday 7,
		# the numeral is the day of the month
		if(($#ARGV >= 0) && ($ARGV[0] =~ /^[0-9]+$/))
		{ set(DAY, $ARGV[0] + 0); shift; }

		next;
	}

	# a bare 4-digit number beginning with 19 or 20 is probably a year
	if($arg =~ /^(19[0-9][0-9])|^(2[0-9][0-9][0-9])$/)
	{	set(YEAR, $arg - 1900);	next;	}

        # @1234 means seconds in epoch time
        if($arg =~ /^@([0-9]+)$/)      {
		@lt=localtime($1+0);
		# Date has been replaced, prev changes are now irrelevant
		for($n=0; $n<8; $n++) { $changed[$n]=undef; }
		next;
	}

        # Checks for YYYYMMDD or YYYY/MM/DD time
        if(($arg =~ /^([0-9]{4})([\/-])([0-9]{1,2})\2([0-9]{1,2})$/) ||
		($arg =~ /^([0-9]{4})()([0-9]{2})([0-9]{2})$/))
        {
		set(YEAR, $1-1900); set(MON, $3-1); set(DAY, $4+0);

		# Set time variables which haven't been set already
		if(!defined($changed[HOUR]))
		{ set(SEC,0); set(MIN,0); set(HOUR,0); }

                next;
        }

        # HH:MM:SS times.  Sub-second times are allowed but ignored
        if($arg =~ /([0-2]?[0-9]):([0-5][0-9])(:([0-5][0-9])(.[0-9]+)?)?$/)
        {
		if(defined($4)) { set(SEC, $4+0); }
		else		{ set(SEC, 0); }

		set(MIN, $2+0);	set(HOUR, $1+0);

		# Handle time with PM in it
		if($#ARGV < 0) { }
		elsif($ARGV[0] eq "pm")  { set(HOUR, pm($lt[HOUR])); shift; }
		elsif($ARGV[0] eq "am")  { set(HOUR, am($lt[HOUR])); shift; }
                next;
        }

        # Times like 9 AM
        if(($arg =~ /^([0-9]+)$/) && ($#ARGV>=0) && ($ARGV[0] =~ /^(am|pm)$/)) {
		$arg=$arg + 0;

		set(SEC, 0); set(MIN,0); set(HOUR, $arg);
		if($ARGV[0] eq "am") { set(HOUR, am($lt[HOUR])); }
		else                 { set(HOUR, pm($lt[HOUR])); }
		shift;
		next;
	}

	# Redundant, but whatever
        if($arg =~ /^now$/)  {
		@lt=localtime(time);
		# Date has been replaced, prev changes are now irrelevant
		for($n=0; $n<8; $n++) { $changed[$n]=undef; }
		next
	}

	# last second/minute/hour/week/year
	if($arg =~ /^(last)|(next)$/)
	{
		if(defined($1)) { $sign=-1; } else { $sign=1; }

		if($#ARGV < 0)
		{
			if(!$quiet)
			{	print STDERR "next what, exactly?\n"	}

			next;
		}

		if(defined($mult{$ARGV[0]}))
		{
			@lt=localtime(time);
			# Date has been replaced, prev changes now irrelevant
			for($n=0; $n<8; $n++) { $changed[$n]=undef; }
			$offset *= $mult{$ARGV[0]};
		}
		# Adding months can't be handled in offset sadly
		elsif(($ARGV[0] eq "month") || ($ARGV[0] eq "months"))
		{	add_month($sign);	}
		elsif(!$quiet)
		{
			print STDERR $ARGV[0]." not a valid option for next\n";
		}

		shift;
		next;
	}

        if(! $quiet) { print STDERR "Unknown argument $arg\n"; }
}

# If there are any arguments left, we found a +/- and need to process
# that time offset.
while(defined($arg=shift))
{
        if(length($arg) == 0){ next; } # Empty string?  Ignore

	if(($arg eq "plus") || ($arg eq "+"))	{ $sign=1; next; }
	if(($arg eq "minus") ||($arg eq "-"))	{ $sign=-1; next; }

	# A number followed by a type, "9" "years"
	if(($arg =~ /^[0-9]+$/) && ($#ARGV >= 0))
	{
		my $arg2=shift;

		if((! $sign)&&(!$quiet))
		{
			print STDERR "Warning, no sign for numeric value\n"
		}

		# second/minute/hour/day/week/year are just multiplication
		if(defined($mult{$arg2}))
		{ $offset += $mult{$arg2} * $arg * $sign; next; }
		# No exact number of seconds per month, just count
		elsif(($arg2 eq "month")||($arg2 eq "months"))
		{ add_month($sign * $arg); next; }

		# Leave for error handler below to find
		$arg=$arg2;
	}

	# If we get here, something went wrong.
	if(!$quiet) {
		print STDERR "Unknown syntax ".$ARGV[0]."\n";
	}
}

my $nref=mktime(@lt); # Convert the altered @lt values back into epoch time

# Sanity checking.  If localtime(mktime(@lt)) produces different values
# from what was in @lt, we must have given it a nonsensical value which
# mktime corrected.
my @san=localtime($nref);

# Titles for localtime() array elements
my @title=("Seconds","Minutes","Hours","Day","Month","Year","Weekday");

for($n=0; $n<=6; $n++)
{
	if(($quiet == 0) && defined($changed[$n]) && ($changed[$n] != $san[$n]))
	{
		printf STDERR "%s changed, inconsistent input?", $title[$n];
		printf STDERR "\t%s in %s out\n", $changed[$n], $san[$n];
	}
}

# Print the calculated time plus offset
print strftime($cmdstr."\n", localtime($nref + ($offset)));
exit(0);

#########################################################################
################################ SUBROUTINES ############################
#########################################################################

# Adds or subtracts a number of months to the time in @lt,
# accounting for year wraparound when the number goes above 11 or below 0
sub add_month {
	$lt[MON] += shift;
	while($lt[MON] >= 12) { $lt[YEAR]++; $lt[MON] -= 12; }
	while($lt[MON] < 0) { $lt[MON] += 12; $lt[YEAR] --; }

	set(MON, $lt[MON]);
	set(YEAR, $lt[YEAR]);
}

# Alter a value in @lt, and mark that index as 'changed' by altering
# the value in @changed too
sub set { my ($i,$v)=(shift,shift); $lt[$i]=$changed[$i]=$v; }

# Takes a numeric AM hour, returns a number in 24-hour time
sub am { if($_[0] == 12) { return($_[0] - 12); } return($_[0]); }
# Takes a numeric PM hour, returns an hour in 24-hour time
sub pm { if($_[0] >= 1) { return($_[0] + 12); } return($_[0]); }

# loadhash(\%hash, "A;B", "a;b")
# sets $hash{A}=0, $hash{B}=1, $hash{a}=0, $hash{b}=1
sub loadhash {
        my ($h,$n)=(shift,0);
	foreach(@_)	{
		$n=0; foreach(split('[;\n]', lc($_))) { ${$h}{$_}=$n++; }
	}
}


Last edited by Corona688; 06-06-2016 at 12:22 PM..
This User Gave Thanks to Corona688 For This Post:
# 17  
Old 06-06-2016
Hooray! I found a bug! add_months vs add_month. Fixed in v0.1.0.
This User Gave Thanks to Corona688 For This Post:
# 18  
Old 02-27-2017
In another thread you say that strftime() should handle %s - but it does not in Solaris 10 and HP-UX 11.31!
I suggest to add a line in the perl code:
Code:
# Parse commandline arguments
while(defined($arg=shift)) {
        if($arg =~ /^--date=(.*)/)  {       $input=$1;                  }
        elsif($arg eq "-d")         {       $input=shift;               }
        elsif($arg =~/^\+(.*)/)     {       $cmdstr=$1;
           if ($cmdstr=~/(?<!%)%s/) { my $t=time; $cmdstr=~s/(?<!%)%s/$t/g; } }
        elsif($arg eq "-q")         {       $quiet=1;                   }


Last edited by MadeInGermany; 02-27-2017 at 02:26 PM.. Reason: a lookbehind catches %%s
This User Gave Thanks to MadeInGermany For This Post:
# 19  
Old 02-27-2017
Thanks for catching that.
Login or Register to Ask a Question

Previous Thread | Next Thread

8 More Discussions You Might Find Interesting

1. UNIX for Beginners Questions & Answers

General Purpose XML Processing

I've been kicking this around for a while now, I might as well post it here. v0.0.9, now properly supporting self-closing tags. v0.0.8, an important quoting fix and a minor change which should handle special <? <!-- etc. tags without seizing up as often. Otherwise the code hasn't changed much.... (6 Replies)
Discussion started by: Corona688
6 Replies

2. Shell Programming and Scripting

Script to determine Date,TotalFile,total size of file based on date

I have file listed like below -rw-r--r--+ 1 test test 17M Nov 26 14:43 test1.gz -rw-r--r--+ 1 test test 0 Nov 26 14:44 test2.gz -rw-r--r--+ 1 test test 0 Nov 27 10:41 test3.gz -rw-r--r--+ 1 test test 244K Nov 27 10:41 test4.gz -rw-r--r--+ 1 test test 17M Nov 27 10:41 test5.gz I... (5 Replies)
Discussion started by: krish2014
5 Replies

3. UNIX for Dummies Questions & Answers

Purpose of - (hypen) in script or command line

Hi, I am new for unix and I am following ABS guide. What is the purpose of - (hypen ) in the below command and What it will do in this?. Can anyone explain it in detail. Rest of the things in the below command I understood somewhat. (cd /source/directory && tar cf - . ) | (cd /dest/directory &&... (1 Reply)
Discussion started by: gwgreen1
1 Replies

4. Shell Programming and Scripting

script to fill up disk space for testing purpose

Hello everyone I am new to this forum I am working on a project and needed a test script to fill up a disk partition /tmp/data to see how the program fails. The system I am working on is a redhat 5.3. Is there anything out there? Thanks. (10 Replies)
Discussion started by: dp100022
10 Replies

5. Shell Programming and Scripting

awk (?) help or just general script

I have two files (___ represents blanks) Foo1 1000 345 456 1001 876 908 1002 ___ 786 1003 643 908 1004 345 234 and Foo2 1000 345 1001 876 1002 111 1003 643 1004 345 (3 Replies)
Discussion started by: garethsays
3 Replies

6. Shell Programming and Scripting

General Q: how to run/schedule a php script from cron jobs maybe via bash from shell?

Status quo is, within a web application, which is coded completely in php (not by me, I dont know php), I have to fill out several fields, and execute it manually by clicking the "go" button in my browser, several times a day. Thats because: The script itself pulls data (textfiles) from a... (3 Replies)
Discussion started by: lowmaster
3 Replies

7. UNIX for Dummies Questions & Answers

whats the purpose of the following script?

whats the purpose of the following script? who could run it? To what is the script refering that exceeds 75%? The mailbox? What does sed 's/%//' do? (1 Reply)
Discussion started by: vrn
1 Replies

8. UNIX for Dummies Questions & Answers

Looking for a general purpose System Monitor

Does anyone have any scripts or suggestions on a general purpose Unix/Linux monitoring tool? (5 Replies)
Discussion started by: darthur
5 Replies
Login or Register to Ask a Question