When − a minimalistic personal calendar program


     when [options] [commands]

     The basic idea is just to type ‘when’ at the command
line. The first time you run the program, it will prompt you
for some setup information. To edit you calendar file in
your favorite editor, do ‘when e’. The basic format of the
calendar file is like this:

             2003 feb 3 , Fly to Stockholm to accept Nobel Prize.

     Once you have a calendar file, running the program as
plain old ‘when’ from the command line will print out the
things on your calendar for the next two weeks.

i       Print upcoming items on your calendar. (This is the
        default command.)

c       Print calendars (grids like on a wall calendar, not
        showing items) for last month, this month, and next

e       Invoke your favorite editor to edit your calendar

w,m,y   Print items for the coming week, month, or year,
        rather than for the default period of two weeks.

j       Print the modified Julian day (useful for finding
        the time interval between two dates).

d       Print nothing but the current date.

All of the following options, except −−help, can be set in
the preferences file. True/false options can be set on the
command line as −−option or −−nooption, and in the
preferences file by setting the option to 0 or 1.

−−help  Prints a brief help message.

        Prints a brief message, including a statement of
        what version of the software it is.

        Set the language to LANG. See the section below on
        internationalization.  This option is not normally
        needed, because the language is automatically


        How many days into the future the report extends.
        Default: 14

        How many days into the past the report extends. Like
        the −−future option, −−past is interpreted as an
        offset relative to the present date, so normally you
        would want this to be a negative value. Default: −1

        Your calendar file. The default is to use the file
        pointed to by your preferences file, which is set up
        the first time you run When.

        Command used to invoke your editor. Default: "emacs
        −nw" Example:  when −−editor="vim"

        Number of columns of text for the output (or 0 if
        you don’t want wrapping at all). Default: 80

        Attempt to detect the width of the terminal, and set
        the width of the output accordingly. This applies
        only if the output is a tty, and is subject to any
        maximum set by −−wrap_max. Overrides any value set
        by −−wrap. Default: no

        Maximum number of columns of text for the output (or
        −1 if you don’t want any maximum). Useful in
        combination with −−wrap_auto to preserve legibility
        on very large terminal windows. Default: −1

        Number of rows of text that will fit in the terminal
        window.  When listing your calendar, output will be
        truncated to this length, unless that would result
        in listing less than three days into the future.
        This behavior is overridden (the maximum number of
        rows is set to infinity) if the −−future option is
        given explicitly, or if the m or y command is used.
        Default: 40

        Attempt to detect the height of the terminal, rather
        than using the value set in the −−rows option. This
        applies only if the output is a tty.  Overrides any
        value set by −−rows. Default: yes

        Print headers at the top of the output of the i, c,


        w, m and y commands.  Default: yes

        When the output is longer than the value set by rows
        or rows_auto, use a pager to display the output.
        (The PAGER and LESS environment variables are
        respected. If PAGER isn’t set, the default is
        "less.") Default: yes

        Extra options if the pager is "less." Default:

        Whether to change accented characters to unaccented
        ones.  Default: yes, unless the $TERM environment
        variable equals "mlterm" or "xterm".

        If the output is a terminal, should we use ANSI
        terminal codes for styling? Default: yes

        Style the output even if it’s not a terminal.
        Default: no


        The first of these says how to style today’s date
        when doing the calendar (c) command.  The second
        says how to style the word ‘‘today’’ when doing the
        items (i) command.  Defaults: bold

        The styling of output can be specified using the
        following keywords: bold, underlined, flashing.  To
        change the color of the text, use these: fgblack,
        fgred, fggreen, fgyellow, fgblue, fgpurple, fgcyan,
        fgwhite.  To change the background color, use
        similar keywords, but with bg instead of fg.
        Example: when
        −−calendar_today_style="bold,fgred,bgcyan" c

        Pipe the calendar file through a program before
        reading it. Default: ""

−−now="Y M D"
        Pretend today is some other date.

        The default behavior of "when c" is to print out
        calendars for last month, this month, and next
        month. By choosing −−noneighboring_months, you can


        avoid printing out months not included in the range
        set by −−past and −−future.

        Start the week from Monday, rather than Sunday.
        Default: no

        Calculate Easter according to the Orthodox Eastern
        Church’s calendar. Default: no

        Display the time of day using 12−hour time, rather
        than 24−hour time. Also affects the parsing of input
        times.  Default: yes

        When times are input with hours that are less than
        x, and AM or PM is not explicitly specified,
        automatically assume that they are PM rather than
        AM. Default: 0

        Only display items that are given as literal dates,
        e.g., "2008 jul 4". Don’t display items that are
        defined by expressions, e.g., periodic items like
        "w=thu". Default: no




        These options are used internally for building and

When is an extremely simple personal calendar program, aimed
at the Unix geek who wants something minimalistic. It can
keep track of things you need to do on particular dates.
There are a lot of calendar and ‘‘personal information
manager’’ programs out there, so what reasons are there to
use When?

It’s a very short and simple program, so you can easily
    tinker with it yourself.

It doesn’t depend on any libraries, so it’s easy to install.
    You should be able to install it on any system where
    Perl is available, even if you don’t have privileges for
    installing libraries.


Its file format is a simple text file, which you can edit in
    your favorite editor.

     Although When should run on virtually any operating
system where Perl is available, in this document I’ll assume
you’re running some flavor of Unix.

While logged in as root, execute the following command:

            make install

     Run When for the first time using this command:


     You’ll be prompted for some information needed to set
up your calendar file.

If you run When again after the initial setup run, it should
print out a single line of text, telling you the current
date. It won’t print out anything else, because your
calendar file is empty, so you don’t have any appointments
coming up.

     Now you can start putting items in your calendar file.
Each item is a line of text that looks like this:

             2003 feb 3 , Fly to Stockholm to accept Nobel Prize.

     A convenient way to edit your calendar file is with
this command:

             when e

     This pops you into your favorite editor (the one you
chose when you ran When for the first time).

     The date has to be in year‐month‐day format, but you
can either spell the month or give it as a number. (Month
names are case‐insensitive, and it doesn’t matter if you
represent February as F, Fe, Feb, Februa, or whatever.  It
just has to be a unique match. You can give a trailing .,
which will be ignored. In Czech, "cer" can be used as an
abbreviation for Cerven, and "cec" for Cervenec.) Extra
whitespace is ignored until you get into the actual text
after the comma. Blank lines and lines beginning with a #
sign are ignored.

     If you now run When, it will print out a list of all
the items in your calendar file that fall within a certain
time interval. (The interval starts from yesterday. When
tries to pick the end of the time interval so that its
output fits on your terminal window, but it will always be
at least three days, and no more than two weeks in the


future.)  To see all your items for the next month, do
‘‘when m’’, and similarly for a year, y, or a single week,

     If you do ‘‘when c’’, When prints out calendars for
last month, this month, and next month.

     You can combine these commands. For instance, ‘‘when
cw’’ will print out calendars, and then show you your items
for the next week.

     For events that occur once a year, such as birthdays
and annivesaries, you can either use a * in place of the

             * dec 25 , Christmas

     or use a year with an asterisk:

             1920* aug 29 , Charlie Parker turns \a, born in \y

     In the second example, \a tells you how old Charlie
Parker would be this year, and \y reproduces the year he was
born, i.e., the output would be:

             today     2003 Aug 29 Charlie Parker turns 83, born in 1920

     For things you have to do every week, you can use an
expression of the form w=xxx, where xxx is the first few
letters of the name of the day of the week in your language.
(You have to supply enough letters to eliminate ambiguity,
e.g., in English, w=th or w=tu, not just w=t.)  Example:

             w=sun , go to church, 10:00

     You can actually do fancier tests than this as well;
for more information, see the section ’fancy tests’ below.
Here’s how to set up some common holidays:

             m=jan & w=mon & a=3 , Martin Luther King Day
        * feb 14 , Valentine's Day
        m=feb & w=mon & a=3 , Washington's Birthday observed
        m=may & w=sun & a=2 , Mother's Day
        m=may & w=mon & b=1 , Memorial Day
        m=jun & w=sun & a=3 , Father's Day
        * jul 4 , Independence Day
        m=sep & w=mon & a=1 , Labor Day
        m=oct & w=mon & a=2 , Columbus Day
        m=oct & w=mon & a=2 , Thanksgiving (Canada)
        * nov 11 , Armistice Day
        m=nov & w=thu & a=4 , Thanksgiving (U.S.)
        e=47 , Mardi Gras
        e=46 , Ash Wednesday
        e=7 , Palm Sunday


        e=0 , Easter Sunday
        e=0−49 , Pentecost (49 days after easter)

     In the U.S., when certain holidays fall on a weekend,
federal workers, as well as many private employees, get a
Monday or Friday off. The full list is given at
If you want a reminder of both the holiday and the day you
get off from work, here’s an example of how you would set
that up:

             * jul 4 , Independence Day
        m=jul & c=4 , Independence Day (observed as a federal holiday)

When has at least partial support for Czech, Danish, Dutch,
English, French, German, Greek, Hungarian, Italian, Polish,
Romanian, and Spanish.  If When has not been translated into
your language, or has only been partially translated, the
text that hasn’t been translated will be displayed in
English.  When should automatically detect what language you
use (via your $LANG environment variable), and if When has
been translated into that language, that’s what you’ll get
‐‐ When’s output will be in your language, and When will
also expect you to use that language in your calendar file
for the names of the months and the days of the week.

     Your calendar file must be in UTF−8 (or ASCII, which is
a subset of UTF−8).  If your calendar file is in some other
encoding, such as ISO−8859, When will typically be able to
detect that, and will refuse to read it.  Command‐line
options can also contain UTF−8.

     Some terminal emulators (aterm, ...) display accented
characters as garbage, but others (mlterm, xterm...) can
display them correctly.  When checks the $TERM environment
variable, and if it equals "mlterm" or "xterm", then
accented characters will be displayed. Otherwise, they are
filtered out of the output.  You can override this by
putting a line like

             filter_accents_on_output = 0


             filter_accents_on_output = 1

     in your ~/.when/preferences file. I’d be interested in
hearing from any users who can suggest a better mechanism
for this than attempting to interpret the $TERM variable.

     On input, accents are allowed, but not required, e.g.,
in a French‐language input file, the date 2005 Fev 17 could
be given with an accented e or an unaccented one, and either
will work. If an input month or day of the week does not


match any of the ones for your language, then When will try
to interpret it as English instead.

     You can put a line like

             language = fr

     in your preferences file to set your language, or
supply the −−language option on the command line, but that’s
not necessary if your $LANG environment variable is set

Each line consists of something like this:

             variable = value

     Whitespace is ignored everywhere except inside the
value. Variable names are case‐insensitive. Blank lines are

A useful command to have your shell execute when you log in
is this:

             when −−past=0 −−future=1

     To print out a calendar for a full year to come:

             when −−past=0 −−future=365 c

Your calendar doesn’t do you any good if you forget to look
at it every day. An easy way to make it pop up when you log
in is to make your .xsession or .xinitrc file look like

             /usr/bin/when −−past=0 −−future=1 &>~/when.today
        emacs −geometry 70x25 −bg bisque ~/when.today &

     The .xsession file is used if you have a graphical
login manager set up on your machine, the .xinitrc if you
don’t. In this example, the first line outputs your calendar
to a file. The complete path to the When program is given,
because your shell’s path variable will not yet be properly
initialized when this runs. The second line pops up a GUI
emacs window, which is distinctively colored so that it will
catch your eye. The last line starts your window manager,
KDE in this example. Whatever window manager you use, just
make sure to retain the preexisting line in the file that
starts it, and make sure that that line is the very last one
in the file.


If you want the various items that lie on a single day to be
printed out in a certain order, the simplest way to do it is
to put them in that order in the input file. That method
won’t work, however, when some of the items lie on dates
that are determined by expressions rather than given
explicitly. The most common reason for wanting to do this
kind of thing is that you have things you need to do at
certain times during the day, and you want them sorted out
by time. In this situation, you can give a time at the
beginning of the item’s text, and When will recognize that
and sort the items by time. Times can be in h:mm or hh:mm
format. If −−ampm is set, then an optional suffix a or p can
be used for AM or PM, e.g., 9:30a for 9:30 AM. If you use
AM/PM time, then you can also, e.g., set −−auto_pm=9 so that
hours less than 9 are automatically assumed to be PM. Here
is an example:

             2010 apr 25 , 7:00 dinner at the anarcho−syndicalist commune
        w=sun , 10:00 church

     April 25, 2010 is a Sunday, so on that date both of
these items will be displayed.  If −−auto_pm is set to 8 or
higher, then the 7:00 will automatically be interpreted as
7:00 PM, and the dinner date will be displayed below the
morning church ceremony.

In addition to w, discussed above, there are a bunch of
other variables you can test:

             w  −  day of the week
        m  −  month
        d  −  day of the month
        y  −  year
        j  −  modified Julian day number
        a  −  1 for the first 7 days of the month, 2 for the next 7, etc.
        b  −  1 for the last 7 days of the month, 2 for the previous 7, etc.
        c  −  on Monday or Friday, equals the day of the month of the nearest weekend day; otherwise −1
        e  −  days until this year's (Western) Easter
        z  −  day of the year (1 on New Year's day)

     You can specify months either as numbers, m=2, or as
names in your language, m=feb.  You can also use the logical
operators & (and) and | (or). The following example reminds
you to pay your employees on the first and fifteenth day of
every month:

             d=1 | d=15 , Pay employees.

     This example reminds you to rehearse with your band on
the last Saturday of every month:

             w=sat & b=1 , Rehearse with band.


     The following two lines

             * dec 25 , Christmas
        m=dec & d=25 , Christmas

     both do exactly the same thing, but the first version
is easier to understand and makes the program run faster.
(When you do a test, When has to run through every day in
the range of dates you asked for, and evaluate the test for
each of those days. On my machine, if I print out a calendar
for a whole year, using a file with 10 simple tests in it,
it takes a few seconds.)  Parentheses can be used, too.

     Depending on your nationality and religion, you
probably have a bunch of holidays that don’t lie on fixed
dates. In Christianity, many of these (the "movable feasts")
are calculated relative to Easter Sunday, which is why the e
variable is useful.

     There is a not operator, !:

             w=fri & !(m=dec & d=25) , poker game

     There is a modulo operator, %, and a subtraction
operator, −.  Using these, along with the j variable, it is
just barely possible for When’s little parser to perform the
following feat:

             !(j%14−1) , do something every other Wednesday

     The logic behind this silly little piece of wizardry
goes like this.  First, we determine, using the command
‘when j −−now="2005 jan 26"’, that the first Wednesday on
which we want to do this has a Julian day that equals 1,
modulo 14. Then we write this expression so that if it’s a
Wednesday whose Julian day equals 1, modulo 14, the quantity
in parentheses will be zero, and taking its logical negation
will yield a true value.

     The operators’ associativity and order of priority
(from highest to lowest) is like this:

             left    %
        left    −
        left    < > <= >=
        left    = !=
        right   !
        left    &
        left    |

If your calendar file gets too large, you may prefer to
split it up into smaller chunks ‐‐ perhaps one for
birthdays, one for Tibetan holidays, etc.  An easy way of
accomplishing this is to install the program m4, put the



             prefilter = m4 −P

     in your preferences file, and then put lines in your
calendar file like this:


$LANG to automatically detect the user’s language

     $TERM to try to figure out if the terminal emulator can
display accented characters

$HOME/.when/calendar − The default location for the user’s
calendar (pointed to by the preferences file)

     $HOME/.when/preferences − The user’s preferences.

When’s web page is at

             http://www.lightandmatter.com/when/when.html   ,

     where you can always find the latest version of the
software.  There is a page for When on Freshmeat, at

             http://freshmeat.net/projects/when/   ,

     where you can give comments, rate it, and subscribe to
e−mail announcements of new releases.

When was written by Ben Crowell,
http://www.lightandmatter.com/personal/.  Dimiter
Trendafilov wrote the new and improved parser for date

Copyright (C) 2003−2012 by Benjamin Crowell.

     When is free software; you can redistribute it and/or
modify it under the terms of the GPL, or, optionally, Perl’s