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>

Replies are listed 'Best First'.
Trust your feelings, Luke!
by Elgon (Curate) on Mar 13, 2001 at 21:42 UTC
    Firstly, respect to dws, good node, good code.

    Secondly: Listen to your intuition, it can tell you things you didn't know that you knew.

    As pointed out it can help you when you have a specific situation in hand and you are trying to resolve it but sometimes, just sometimes, it can warn you that you've done something stupid. Many times when I have been coding, shooting in a match (my hobby) or doing chemistry lab work (my degree) I get this nasty feeling, as if something is out of place: Nine times out of ten there is something I have forgotten or not taken into account.

    A good example was when I was playing with a mail filter at work which was supposed to take mails with a certain sequence of headers and forward them internally for handling by a Perl script, as it so happens. I'd set this up but hadn't set it running yet when I took a cigarette and caffeine break. I started to get the strange feeling that I had made a serious cockup, not just the will-it/won't-it work kind of feeling I get when I first launch a script or similar. I realised after that I had forgotten to change the relevant mail headers, which, as I found out after I checked with someone else, could possibly have resulted in an infinite loop of emails, augmenting by one in number each cycle. Ooops, can anyone say "network thrash"?

    You might be wrong but won't you be happy and won't your confidence get a boost if you find out that your code will work?

    Elgon

Re: On the peril of discounting intuition
by japhy (Canon) on Mar 13, 2001 at 20:45 UTC
    That's why I never use: timelocal(0, 0, 0, 1, 0, 2001). I always use noon. It's safe.

    japhy -- Perl and Regex Hacker
      Or, if you're going to going to be subtracting 24 hours for purposes of getting a name for yesterday's log file, arrange to run your cron(1) job after 3am. At least under the U.S. daylight savings adjustment rules, that'll be safe.
        Although the "subtracting hours" method is highly risky, for a variety of reasons, it does work if you use it within reason.

        It would be highly advisable to subtract 26 hours from noon on the day in question, which allows for those wacky time zones which shift 1.5 hours. This should put you at anywhere from 10am to 12pm on the day prior, depending on how wacky the time zone in question is. It should never, though put you more than a single day back. The UNIX time system thankfully can't represent time around the Gregorian Reformation of 1582 which skipped 10 days(!) to make the calendar Leap Year Compliant.

        ObUselessFact:
        BTW, there are more than 60 seconds in a minute. Every year the atomic clock people add or subtract several "leap seconds" to make sure that noon is noon. This is the fundamental difference between GMT and UCT (Universal Coördinated Time). With all the water, air, wind, and tectonic movement, the Earth is not spinning at a precise rate, and corrections must be made to keep things exactly on time. However, unless your computer had an atomic clock in it that was constantly synchronized to UCT, you shouldn't worry too much about this.
(arturo) Re: On the peril of discounting intuition
by arturo (Vicar) on Mar 13, 2001 at 20:59 UTC

    Intuition, feh ... sort of =)

    Your intuition can be educated, or not. A lot of what feels like intuition is definitely affected by your experience. It's a rare person indeed who has something more-or-less innate when it comes to programming (pick your favourite endeavour here). You can develop a good 'eye' for what's going to work and what isn't, and if you work at things long enough, that 'eye' becomes part of your nature. And yes, some people are just better at this sort of thing than others. So, to that extent, intuition is highly useful and ought to be heeded, at least provisionally.

    Note though, when it came to justifying your intuition, you had a way of working out why it was right. If you didn't have that, I would have said "intuition, feh. Show me *why* that will work".

    Philosophy can be made out of anything. Or less -- Jerry A. Fodor