My intuition spoke up yesterday. It was wrong, and so was I when I said it was wrong.

In the threads Date and How to find yesterdays date (was: Date), someone said that a way to determine yesterday's date was to use

(undef, undef, undef, $day, $month, $year, undef) = localtime(time() - 24*60*60);
I followed my intuition, and responded that this would be wrong during one hour each year in timezones that made daylight savings changes.

Something still seemed wrong, so I did some research into daylight savings time (a fascinating topic, full of oddball laws, de facto laws, and downright craziness), ran a simple experiment, and retracted the claim, saying that the "subtract 24 hours" method would indeed work.

Unfortunately, the research and subsequent thinking were done too late at night, and the experiment was "flawed" (read: brain damaged).

Wrong not once, but twice. How embarrasing.

At a meta level, this is a good example of how our intuition can often put us on the right track, only to be overridden and discounted by our rational mind. Sometimes our rational mind picks up some flaw in what our intuition is saying and uses that as justification, but occassionaly it's just a matter of our rational mind being, well, wrong.

The moral is that when our intuition is speaking, we dismiss it at our peril. The mere fact that our intuition is speaking should give us greater pause. Our intuition may not be right, but it's not necessarily wrong. It's like a stupid hunting dog on point at a bush. There may not be a bird in that particular bush, but that's no reason to walk away without first checking nearby bushes.


Here's a more complete experiment. It shows that determining yesterday's date by the "subtract 24 hours" method is actually wrong during two one-hour periods each year, and that adding 24 hours to determine tomorrow's date is also wrong during two different one-hour periods. Once you think about this a while, it's kind of a "well, duh" problem.
# Determine how many hours in a year cause problems when # subtracting/adding 24 hours to yield the previous/next # date. use strict; use Time::Local; my $start = timelocal(0, 0, 0, 1, 0, 2001); foreach my $hour ( 0 .. 24 * 365 ) { check($start + $hour * 60 * 60); } sub check { my $time = shift; # Method 1 - subtract 24 hours from the given time # to determine yesterday's date my $timeMinus24 = $time - 24 * 60 * 60; my $dm1 = join ' ', (localtime($timeMinus24))[3,4]; # Method 2 -- substract 2 hours from the start of the day # to determine yesterday's date my ($m,$d,$y) = (localtime($time))[3,4,5]; my $daystart = timelocal(0, 0, 0, $m, $d, $y); my $dm2 = join ' ', (localtime($daystart - 2 * 60 * 60))[3,4]; print "-24 wrong at ", scalar localtime($time), "\n" if $dm1 ne $dm2; # Method 1 -- add 24 hours to the given time # to determine tomorrow's date my $timePlus24 = $time + 24 * 60 * 60; $dm1 = join ' ', (localtime($timePlus24))[3,4]; # Method 2 -- add 26 hours to the start of the day # to determine tomorrow's date $dm2 = join ' ', (localtime($daystart + 26 * 60 * 60))[3,4]; print "+24 wrong at ", scalar localtime($time), "\n" if $dm1 ne $dm2; }
yields
+24 wrong at Sat Mar 31 23:00:00 2001 -24 wrong at Mon Apr 2 00:00:00 2001 +24 wrong at Sun Oct 28 00:00:00 2001 -24 wrong at Sun Oct 28 23:00:00 2001

Edit 2001-03-13 by tye to add <READMORE>


In reply to On the peril of discounting intuition by dws

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.