As a part of my general interest in time management, I wanted to take a look into the UNIX utility CALENDAR, which is a reminder service, that is used on the console.

What is CALENDAR?

CALENDAR is a reminder service and default system utility on FreeBSD and UNIX operating systems. CALENDAR offers simple, effective and secure time management for systems administrators and users. CALENDAR is based on text files, which makes it easy to update, synchronize and backup.

$ calendar
Aug 20 Weather forecast says 11-17 °C 💧
Aug 20* Daily coffee meeting with David Lightman at 15:00
Aug 20 Patch WOPR mainframe in data center
Aug 20 Simulate first-strike on WOPR
Aug 20 Change password for listing games on WOPR

Calendar files

The CALENDAR reminder service uses one or more calendar files. Much like the good old days, when you would have one or more calendars. You might have a private one for personal events, one for recurring birthdays, a shared one for family events and a shared one for project events. Each calendar can hold tasks, recurring events.

By default, CALENDAR will search for a calendar file in the user home. If that is not found, then it will look for a calendar file in the hidden dot calendar directory and the following shared directories. The default name for a calendar is “calendar”.

~
~/.calendar
/usr/local/share/calendar
/usr/share/calendar

Creating calendar files

I recommend, that the hidden calendar directory is used. This protect the calendars from accidental deletion. In this example, a calender for one-time events and a calendar for recurring events is created.

$ mkdir -m 700 ~/.calendar
$ touch ~/.calendar/calendar
$ touch ~/.calendar/calendar.recurring
$ chmod 600 ~/.calendar/*

Calendar file syntax and format

The calendar file format is text based and consist of a list of dates and description. These are separated by a tab. Other calendars can be included.

$ nano -T 12 ~/calendar/calendar
#include <calender.recurring>
#include <calendar.freebsd>
#include <calendar.weather>
15 * Every 15th
10/2 2nd of October
July Every 1st of July
Thursday Every Thursday
2025/9/15 15th of September 2025
04/TueLast Every last Tuesday in April

Using CALENDAR

If you want to see todays calendar events, then run CALENDAR without any arguments. CALENDAR will read the calendar, and any included calendars, and output todays events. You might want to format the date to your local preference in the shell configuration or on the command line.

$ export LC_TIME=C
$ calendar

If you want to see events, that is planned days ahead in time, or happened days back in time, you can use the ahead argument -A and back argument -B. They can be also combined.

$ calendar -B 1 -A 3

By default, the weekend is shown as one, but by using the argument -W, weekends can be treated as any other day. By default, the output lists today and tomorrow, but by using -W 0, only today is show. If you want to see or test a specific day, you can use the argument -t.

The manual is very well written.

$ man calendar

The FreeBSD calendar

On FreeBSD systems, there is a calendar file, that has birthdays of FreeBSD contributers.

$ cat /usr/share/calendar/calendar.freebsd | grep Percival
02/24 Colin Percival <> born in Burnaby, Canada, 1981

Todays events at login

If you would like, that each user gets todays events at the login console, then configure it in the global shell configuration. In this example, the SH is configured.

# nano /etc/profile
events=$(calendar -W 0 2> /dev/null)
if [ -n "$events" ]; then
echo "$events"
fi

Todays events via email

If you want an automatic daily email with todays events, you can configure CRON to do this. In the following example, CRON on a FreeBSD server is configured to automatically send todays events to each system user.

# nano /etc/crontab
0 8 * * * root LC_TIME=C /usr/bin/calendar -a

Todays weather forecast in calendar

If you want to include todays weather forecast, for today and the next days, you can use an online service, that generate ICS calendar files and convert them to CALENDAR format.

In this example, a special URL to the weather forecast was generated on the brilliant website of Meteomatics, which is a free service. The weather forecast comes as a file in ICS format. This file contains the weather forecast for each day through 15 days. Python is used to convert it to CALENDAR format and saved as an optional calender, that local users can include in their calendars.

# nano ~/bin/meteomatics
#!/usr/bin/env python3.11
from icalendar import Calendar
from datetime import datetime
import re
with open("/tmp/meteomat.ics", "rb") as f:
cal = Calendar.from_ical(f.read())
for component in cal.walk("vevent"):
dtstart = component.decoded("dtstart")
if isinstance(dtstart, datetime):
dt = dtstart.date()
else:
dt = dtstart
desc = component.get("description")
if not desc:
continue
temps = [int(x) for x in re.findall(r"([-]?\d+)°C", desc)]
if not temps:
continue
tmin, tmax = min(temps), max(temps)
rain = "💧" if "💧" in desc else ""
print(f"{dt.month}/{dt.day}\tWeather forecast says {tmin}-{tmax} °C {rain}")

CRON is used to update the weather forecast calendar automatically. In this example, it happens daily.

# nano /etc/crontab
@daily root fetch -o /tmp/meteomat.ics "https://ical.meteomatics.com/calendar/Knippelsbro%202%2C%201409%20K%C3%B8benhavn%20K%2C%20Denmark/55.674679_12.587408/en/meteomat.ics" && /root/bin/meteomatics > /usr/share/calendar/calendar.weather

More about CALENDAR