|
From: grinder <gr...@pe...> - 2001-12-01 15:07:28
|
Hello list, I downloaded the countdown script, because it seemed like a good place to start. My idea is to run all of the nms scripts on http://grinder.perlmonk.org/ to give them a bit of a shakeout. So I configured the date to be 1/1/3001, the countdown to the next millenium. Ran the script. Date has passed. Huh? Then it struck me... the date is based on epoch seconds. So I set the countdown to the end of the epoch. I can just about recite it from memory, 19/1/2038 and a few hours more. Date has passed. Turns out, something somewhere is cutting the dates off at an arbitrary limit: 23:59:29 31/12/2037. One other point: '%c' as a strftime date specifier is a little cryptic. I would tend to prefer '%H:%M:%S %d/%m/%Y'. Regardless of the broken way Americans deal with dates, this is a little more self-documenting and therefore would probably let people modify the format string without having to read the man page. Here's the thing though. The 2038 limit is a little feeble. Does Date::Calc know how to deal with dates beyond the end of the world (as we know it)? Why not eval a require of Date::Calc, and perform an error check on the date to see whether it is in bounds or not, according to whether we can use Date::Calc or not. Also, all those reverse @arrays is a bit ugly. Something needs to be done. Anyway, I haven't really done anything to the script yet, but there are a few things that might be worth diffing. Later, David "grinder" Landgren __DATA__ #! /usr/bin/perl -w # # $Id: countdown.pl,v 1.5 2001/11/25 11:39:38 gellyfish Exp $ # # $Log: countdown.pl,v $ # Revision 1.5 2001/11/25 11:39:38 gellyfish # * add missing use vars qw($DEBUGGING) from most of the files # * sundry other compilation failures # # Revision 1.4 2001/11/13 20:35:14 gellyfish # Added the CGI::Carp workaround # # Revision 1.3 2001/11/13 09:14:41 gellyfish # Added CGI::Carp # # Revision 1.2 2001/11/11 17:55:27 davorg # Small amount of post-import tidying :) # # Revision 1.1.1.1 2001/11/11 16:48:45 davorg # Initial import # use strict; use POSIX qw(strftime); use Time::Local; use CGI qw(:standard); use CGI::Carp qw(fatalsToBrowser set_message); use vars qw($DEBUGGING); # Configuration # # $DEBUGGING must be set in a BEGIN block in order to have it be set before # the program is fully compiled. # This should almost certainly be set to 0 when the program is 'live' # BEGIN { $DEBUGGING = 0; } # @from_date = (yyyy,mm,dd,hh,mm,ss); # Which means: (year,month,day,hour,minute,second) my @from_date = (2037,12,31,23,59,59); my $date_fmt = '%d/%m/%Y %H:%M:%S'; # see 'man strftime' for more examples # $style is the URL of a CSS stylesheet which will be used for script # generated messages. This probably want's to be the same as the one # that you use for all the other pages. This should be a local absolute # URI fragment. my $style = '/grinder.css'; # End configuration BEGIN { my $error_message = sub { my ($message ) = @_; print "<h1>It's all gone horribly wrong</h1>"; print $message if $DEBUGGING; }; set_message($error_message); } $from_date[0] -= 1900; $from_date[1]--; my @diffs = ('X', 12, 'X', 24, 60, 60); if (my $query = query_string()) { $query =~ s/%2C/,/g; $query =~ s/=//g; @from_date = split(/,/, $query); } my @now = reverse((localtime)[0 .. 5]); my $from_date = strftime($date_fmt, reverse @from_date); my $now = strftime($date_fmt, reverse @now); print header(), start_html(-title => "Countdown to: $from_date", -style => {href => $style}); print h1("Countdown to: $from_date"), hr(); my $epoch_now = timelocal(reverse @now); my $epoch_future = timelocal(reverse @from_date); if ($epoch_now > $epoch_future) { print h2('Date has passed'), p("Current = $epoch_now, Target = $epoch_future."), end_html(); exit; } my @days = (31, is_leap($now[0]+1900) ? 29 : 28 , 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); my @diff = ('-') x 6; my @skip = () x 6; foreach (reverse 0 .. $#from_date) { # print "$_: [@from_date][@now][@diff]\n"; if ($from_date[$_] eq 'XX') { $skip[$_] = 1; next; } $diff[$_] = $from_date[$_] - $now[$_]; if ($diff[$_] < 0) { if ($_ == 0) { die "Argh!! Time travel not implemented"; } elsif ($_ == 2) { $diff[$_] += $days[$now[1]]; $now[$_ - 1]++; } else { $diff[$_] += $diffs[$_]; $now[$_ - 1]++; } } } #print " : [@from_date][@now][@diff]\n"; my @units = qw(Year Month Day Hour Minute Second); my $diff; for (0 .. $#diff) { next if $skip[$_]; $diff .= "$diff[$_] $units[$_]"; $diff .= 's' if $diff[$_] != 1; $diff .= "<br>\n"; } print p($diff); print hr(), p("It is currently $now"), end_html(); sub is_leap { my $y = shift; (!($y % 100) && !($y % 400)) || (($y % 100) && !($y % 4)); } __END__ |