#!/usr/bin/perl -w # timediff.pl - outputs a time difference respecting sig figs and grammar # Author: Jed Yang (htam) # Date: 2005.08.24 # I _might_ add a -v option to print words that indicate past or future if requested. use strict; use Time::Local; my $show = 0; my $count = 0; # this outputs a number with units # it is called `grammar' because half of the lines (6/12) deal with English grammar sub grammar { my ($num, $word) = @_; $count--; return if (!$show && !$num); # skip initial 0's, but not middle ones $show = 1; print "$num $word"; print "s" unless (1 == $num); exit if ($count <= 0); if ($count == 1) { print " and "; } else { print ", "; } } # program starts here if (!@ARGV) { print "Usage: countdown.pl year [month [date [hour [min [sec]]]]]\n"; exit 1; } $count = @ARGV; # how many sig figs should the output have? no more than the input, of course if ($count > 6) # why would any one be naughty? { $#ARGV = 5; # this is NECESSARY as we do a reverse on @ARGV later, it should have precisely 6 elements $count = 6; # this is to prevent a trailing comma (and a space) in the output } my $now = time(); # on extremely slow systems, a second or two might elapse, rendering our feature useless my (@now) = localtime $now; # now begins a block of code to make clarify fuzzy timestamps in such a way to make rounding less critical $now[4]++; # use 1-based month for user friendliness for (my $i = @ARGV; $i < 6; $i++) { $ARGV[$i] = $now[5-$i]; } $ARGV[1]--; # use 1-based month for user friendliness # so I know this is VERY hackish, but I don't really care right now my $diff = timelocal(reverse @ARGV) - $now; # hey, why not? if ($diff == 0) { print "now"; exit; } my $sec = abs($diff); # no need to restrict to only counting down, really my $min = int($sec / 60); $sec %= 60; my $hour = int($min / 60); $min %= 60; my $day = int($hour / 24); $hour %= 24; my $month = int($day / 30); my $year = int($day / 365); $day %= 365; # get rid of year $day %= 30; # get rid of month $month %= 12; grammar($year, "year"); grammar($month, "month"); grammar($day, "day"); grammar($hour, "hour"); grammar($min, "minute"); grammar($sec, "second");