######################################################################
    Mindcal 0.01
######################################################################

NAME
    Mindcal - Calculate day-of-week of any given date in your head

SYNOPSIS
      use Mindcal;
      use DateTime;

      my $mc = Mindcal->new(
        date => DateTime->new(
            day   => 1,
            month => 1,
            year  => 2000,
        )
      );

      print "Year item:  ", $mc->year_item(), "\n";
      print "Month item: ", $mc->month_item(), "\n";
      print "Day item:   ", $mc->day_item(), "\n";
      print "Adjust:     ", $mc->adjust(), "\n";
      print "Weekday:    ", $mc->weekday(), "\n";

DESCRIPTION
    This module helps training the necessary mental steps to determine the
    day of the week of any given date in your head.

    The method was invented by Lewis Carroll ("Alice in Wonderland") and
    eloquently described as hack #43 in "Mind Performance Hacks" by Ron
    Hale-Evans, O'Reilly 2006.

    The method involves calculating four different values of a given date in
    your head, the year item, the month item, the day item and an
    adjustment. Once you've calculated those four values, simply add them up
    and calculate the remainder of a division by seven (so that's modulo 7)
    and look up the day of the week in the following table:

        0 Sunday
        1 Monday
        2 Tuesday
        3 Wednesday
        4 Thursday
        5 Friday
        6 Saturday

  The Year Item
    The year item can be determined by the following formula:

        (YY + (YY div 4)) mod 7

    YY is the two-digit year, the century gets discarded. YY of 2007 is
    simply 07.

    The 'div' operator is an ordinary division but it drops the remainder.
    In this way, "7 div 4" is 1. Why? 7/4 results in 1, remainder 3, which
    gets discarded.

    The 'mod' operator is a modulo operation, which is the remainder after
    an ordinary division. "7 mod 4" is 3. Why? 7/4 results in 1, remainder
    3. Only the remainder is kept.

    So, according to the formula above, the year item for the year 2007 is

        (7 + (7 div 4)) mod 7

    which is

        (7 + 1) mod 7

    and therefore 1.

  The Month Item
    The month items are best memorized as a string of numbers:

        01  02  03  04  05  06    07  08  09  10  11  12
         0   3   3   6   1   4     6   2   5   0   3   5

    I personally memorize them as

    *   Start with "033".

    *   Continue with "614" (like 314, which is PI, just start with 6)

    *   Continue with "625" (that's 25*25, the area of a rectangle, as
        opposed to a circle, as suggested by the previously used PI)

    *   End with "035" (that's two more than the start sequence "033")

    It takes some practice to memorize these 12 numbers, but I've found that
    it's quite easy to do if you split it up in two groups of 6 and map the
    desired month number onto the correct group of 6.

    To calculate the month item, look it up in the table above. For example,
    the month item for July is 6.

  The Day Item
    The day item is simply the day of the month. For example, the day item
    for July 27th is 27.

  The Adjustment
    The adjustment is dependent on the century and if the given year is a
    leap year or not. For beginners, I recommend only memorizing the
    following numbers:

        1900 0
        2000 6

    So for a date between 1900 and 1999, the adjustment value is 0. Between
    2000 and 2099, it is 6.

    If the given year is a leap year and the given date is in January or
    February, subtract 1 from the adjustment value. For example, if you want
    to calculate the weekday of 1/1/2000 and you know that 2000 is a leap
    year, the adjustment value is 5. Why? For 2000, according to the table
    above, we have to add 6, but since it's a date in January of a leap
    year, we subtract 1.

    For more advanced users, here's the table for additional centuries:

        1700 4
        1800 2
        1900 0
        2000 6
        2100 4
        2200 2
        2300 0

  Adding it all up
    After adding the year, month, day values and the adjustment, determine
    the remainder after a division by 7 (in math terms, the result of a
    modulo 7 operation).

    For example, to determine the weekday of 11/27/1964, we calculate

    *   a year item of 3

    *   a month item of 3

    *   a day item of 27

    *   an adjustment of 0

    Adding 3+3+27 yields 33, which has a remainder of 5 after a division by
    7 (28 is the next-lowest number divisible by 7 and 33-28=5).

    Looking up 5 in the weekday table yields a Friday. Therefore, 11/27/1964
    is a Friday.

EXAMPLES
    Let's train calculating year items on random years between 1900 and
    2099:

      use Mindcal;
      use DateTime;

      while(1) {
        my $year = 1900 + int rand 200;
        print "$year?\n";
        <>;

        my $mc = Mindcal->new(
            date => DateTime->new(
                day   => 1,
                month => 1,
                year  => $year,
            )
        );

        print "Year item:  ", $mc->year_item(), "\n";
      }

    For a script printing random dates and, on a push of a button, the
    corresponding year, month, day, and adjustment values, try "mindcal"
    which comes with the Mindcal CPAN distribution.

AUTHOR
    Mike Schilli, <m@perlmeister.com>

COPYRIGHT AND LICENSE
    Copyright (C) 2007 by Mike Schilli

    This library is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself, either Perl version 5.8.5 or, at
    your option, any later version of Perl 5 you may have available.