Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!wuarchive!zaphod.mps.ohio-state.edu!sol.ctr.columbia.edu!ira.uka.de!fuchs From: fuchs@it.uka.de (Harald Fuchs) Newsgroups: comp.unix.questions Subject: Re: Why does "cal 9 1752" produce incorrect results? Message-ID: Date: 27 Nov 90 23:31:32 GMT References: <3313@ns-mx.uiowa.edu> <1990Nov27.110212.131@comp.vuw.ac.nz> Sender: news@ira.uka.de (USENET News System) Organization: University of Karlsruhe, FRG Lines: 81 Nathan.Torkington@comp.vuw.ac.nz (Nathan Torkington) writes: >In article <3313@ns-mx.uiowa.edu> khenry@umaxc.weeg.uiowa.edu (Ken Henry) writes: >>Does anybody know why "cal 9 1752" produce incorrect >>results? It seems to be in the Unix systems I >>checked (BSD 4.3, AIX 3.1). >I believe there was a date change sometime, where the civilised world lost >a fortnight to allow the 'old calendar' to become the 'new calendar' which >would be in sync with the seasons ... You seem to think of the Julian -> Gregorian calendar shift, but that was 1582 AD. How about a little perl script? Doesn't handle Julian dates either but should work for the Gregorian calendar. I'm sure one of the Perl lords on the net will come up with a one-liner, but for the time being... ----------------- snip snip snippety snip ------------------------------ #!/usr/local/bin/perl $0 =~ s:.*/::; $[ = 1; # Argument check if ($#ARGV == 1) { $all = 1; $m = 1; $y = shift; } elsif ($#ARGV == 2) { $m = shift; die "$0: bad month \"$m\"\n" if $m !~ /^\d{1,2}$/ || $m < 1 || $m > 12; $y = shift; } else { die "Usage: $0 [month] year\n"; } die "$0: bad year \"$y\"\n" if $y !~ /^\d{4}$/ || $y <= 1582; # First weekday $w = &wday (1, $m, $y) + 1; print "$y\n"; if ($all) { for $m (1..12) { $w = &month ($m, $y, $w); } } else { $w = &month ($m, $y, $w); } sub wday { # (d, m, y) # Day of the week, Gregorian calendar local ($d, $m, $y) = @_; local ($f) = $y * 365 + $d + 31 * ($m - 1); if ($m <= 2) { $y--; } else { $f -= int ($m * 0.4 + 2.3); } $f += int ($y / 4) - int (0.75 * int ($y / 100) + 0.75); # Return 0 for Monday, ..., 6 for Sunday ($f + 5) % 7; } sub month { # (m, y, w) # Print out one month local ($m, $y, $w) = @_; local (@l) = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); $l[2]++ if !($y % 4) && $y % 100 || !($y % 400); local (@n) = (Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec); print "\n$n[$m]\n\n"; local (@wd) = (Mon, Tue, Wed, Thu, Fri, Sat, Sun); local ($_); for (1..$l[$m]) { printf "%s\t%2d\n", $wd[$w], $_; $w = ($w % 7) + 1; } $w; } # local variables: # mode: perl # end: ----------------- snip snip snippety snip ------------------------------ -- Harald Fuchs ... *gulp*