cal
- Display a Calendar in Your Terminal
— 1957 Words — 10 min
This is my first post in the Command Line Monday series. It gives a short introduction to a useful command line tool every Monday.
cal
is part of the
Single UNIX Specification
and is should therefore be installed on every
unix-like operating system.
The official manual
of cal
in the unix specification defines only 3 commands:
$ cal
May 2016
Su Mo Tu We Th Fr Sa
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
$ cal 2015
2015
January February March
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 2 3 1 2 3 4 5 6 7 1 2 3 4 5 6 7
4 5 6 7 8 9 10 8 9 10 11 12 13 14 8 9 10 11 12 13 14
11 12 13 14 15 16 17 15 16 17 18 19 20 21 15 16 17 18 19 20 21
18 19 20 21 22 23 24 22 23 24 25 26 27 28 22 23 24 25 26 27 28
25 26 27 28 29 30 31 29 30 31
April May June
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 2 3 4 1 2 1 2 3 4 5 6
5 6 7 8 9 10 11 3 4 5 6 7 8 9 7 8 9 10 11 12 13
12 13 14 15 16 17 18 10 11 12 13 14 15 16 14 15 16 17 18 19 20
19 20 21 22 23 24 25 17 18 19 20 21 22 23 21 22 23 24 25 26 27
26 27 28 29 30 24 25 26 27 28 29 30 28 29 30
31
July August September
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 2 3 4 1 1 2 3 4 5
5 6 7 8 9 10 11 2 3 4 5 6 7 8 6 7 8 9 10 11 12
12 13 14 15 16 17 18 9 10 11 12 13 14 15 13 14 15 16 17 18 19
19 20 21 22 23 24 25 16 17 18 19 20 21 22 20 21 22 23 24 25 26
26 27 28 29 30 31 23 24 25 26 27 28 29 27 28 29 30
30 31
October November December
Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa
1 2 3 1 2 3 4 5 6 7 1 2 3 4 5
4 5 6 7 8 9 10 8 9 10 11 12 13 14 6 7 8 9 10 11 12
11 12 13 14 15 16 17 15 16 17 18 19 20 21 13 14 15 16 17 18 19
18 19 20 21 22 23 24 22 23 24 25 26 27 28 20 21 22 23 24 25 26
25 26 27 28 29 30 31 29 30 27 28 29 30 31
$ cal 9 2015
September 2015
Su Mo Tu We Th Fr Sa
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
Simple but useful. That's what we love about Unix.
Real world implementations which can be found on Mac OS, BSD
and of course GNU/Linux are, however, much more powerful and have some nifty
additional features.
We'll have closer look at the GNU version, also called gcal
.
It's installed on Ubuntu per default and can
be installed on Mac OS with Homebrew:
brew install gcal
One very useful command for example is
gcal --holiday-list --cc-holiday=<location-code>
or the short form
gcal -n -q <location-code>
,
where <location-code>
is a two letter country code
plus (sometimes) a two letter territory code.
Example output:
$ gcal --holiday-list --cc-holidays=us_ca
Eternal holiday list: The year 2016 is A leap year
New Year's Day (US_CA) + Fri, Jan: 1st:2016 = -51 days
Martin L. King's Day (US_CA) + Mon, Jan:18th:2016 = -34 days
Groundhog Day (US_CA) - Tue, Feb 2nd 2016 = -19 days
President Lincoln's Birthday (US_CA) + Fri, Feb:12th:2016 = -9 days
St Valentine's Day (US_CA) - Sun, Feb 14th 2016 = -7 days
Presidents' Day (US_CA) + Mon, Feb:15th:2016 = -6 days
St Patrick's Day (US_CA) - Thu, Mar 17th 2016 = +25 days
Good Friday (US_CA) * Fri, Mar 25th 2016 = +33 days
Cesar Chavez Day (US_CA) + Thu, Mar:31st:2016 = +39 days
All Fool's Day (US_CA) - Fri, Apr 1st 2016 = +40 days
Prayer Day (US_CA) - Thu, May 5th 2016 = +74 days
Nurses' Day (US_CA) - Fri, May 6th 2016 = +75 days
Mother's Day (US_CA) - Sun, May 8th 2016 = +77 days
Armed Forces Day (US_CA) - Sat, May 21st 2016 = +90 days
Remembrance/Memorial Day (US_CA) + Mon, May:30th:2016 = +99 days
Father's Day (US_CA) - Sun, Jun 19th 2016 = +119 days
Independence Day (US_CA) + Mon, Jul: 4th:2016 = +134 days
Parent's Day (US_CA) - Sun, Jul 24th 2016 = +154 days
Friendship Day (US_CA) - Sun, Aug 7th 2016 = +168 days
Labour Day (US_CA) + Mon, Sep: 5th:2016 = +197 days
Admission Day (US_CA) + Fri, Sep: 9th:2016 = +201 days
Grandparents' Day (US_CA) - Sun, Sep 11th 2016 = +203 days
Citizenship Day (US_CA) - Sat, Sep 17th 2016 = +209 days
Children's Day (US_CA) - Sun, Oct 9th 2016 = +231 days
Columbus Day (US_CA) + Mon, Oct:10th:2016 = +232 days
Sweetest Day (US_CA) - Sat, Oct 15th 2016 = +237 days
Bosses' Day (US_CA) - Sun, Oct 16th 2016 = +238 days
Mother in Law's Day (US_CA) - Wed, Oct 26th 2016 = +248 days
Halloween (US_CA) - Mon, Oct 31st 2016 = +253 days
Veteran's Day (US_CA) + Fri, Nov:11th:2016 = +264 days
Thanksgiving Day (US_CA) + Thu, Nov:24th:2016 = +277 days
Thanksgiving Day (US_CA) + Fri, Nov:25th:2016 = +278 days
Christmas Day (US_CA) + Mon, Dec:26th:2016 = +309 days
Kwanzaa (US_CA) - Mon, Dec 26th 2016 = +309 days
Kwanzaa (US_CA) - Tue, Dec 27th 2016 = +310 days
Kwanzaa (US_CA) - Wed, Dec 28th 2016 = +311 days
Kwanzaa (US_CA) - Thu, Dec 29th 2016 = +312 days
Kwanzaa (US_CA) - Fri, Dec 30th 2016 = +313 days
Kwanzaa (US_CA) - Sat, Dec 31st 2016 = +314 days
There are also countless options to change the display range and the output formatting.
gcal .
- Display the last, the current and the next monthgcal -j
- Display the days as day of the year instead of day of the month (e.g. 342 instead of 7)gcal 3-7
- Display days of month 3 to 7- …
Time range and filtering options can of course also be combined.
Another interesting feature is gcals ability to load calendar entries
from a so called resource file. Basically it's a list of dates and
a corresponding text.
To try it out create the file ~/.gcalrc
with following content:
20160428 1. Write your first "Command Line Monday" post!
00000428 It's John's %B1987 Birthday
0 Today is %>1*K , %>02&*D %U %Y !
0 It's the %>03&*N day of the year.
0 The week number is: %k
0 It's %t* o'clock, Mr. %-USER
0 Hurry up with your work,\
sunrise is at %o+5158+00738+61,2: .
0 Moon phase %>03*O ~Text %Z
If you now run gcal --today
and it was 2016-04-28 or you specify the date with
gcal --list-of-fixed-dates %20160428
(short gcal -c %20160428
)
you get following result:
$ gcal --list-of-fixed-dates %20160428
Fixed date list:
Thu, Apr<28th>2016: 1. Write your first "Command Line Monday" post!
Thu, Apr<28th>2016: Hurry up with your work, sunrise is at 06:03.
Thu, Apr<28th>2016: It's 09:56am o'clock, Mr. adrian
Thu, Apr<28th>2016: It's John's 29 Birthday
Thu, Apr<28th>2016: It's the 119th day of the year.
Thu, Apr<28th>2016: Moon phase 066%-
Text
@@@@@@@@@@ )
@@@@@@@@@@@@@@@@@@ )
@@@@@@@@@@@@@@@@@@@@@ )
@@@@@@@@@@@@@@@@@@@@@@@@ )
@@@@@@@@@@@@@@@@@@@@@@@@@ )
@@@@@@@@@@@@@@@@@@@@@@@@@@@ )
@@@@@@@@@@@@@@@@@@@@@@@@@@@ )
@@@@@@@@@@@@@@@@@@@@@@@@@ )
@@@@@@@@@@@@@@@@@@@@@@@@ )
@@@@@@@@@@@@@@@@@@@@@@ )
@@@@@@@@@@@@@@@@@@ )
@@@@@@@@@@@@ )
Thu, Apr<28th>2016: The week number is: 17
Thu, Apr<28th>2016: Today is Thursday, 28th April 2016!
As you can see gcal has some crazy features. And displaying the current moon phase as well calculating the current sunrise and sunset times are just the beginning. There is even a feature to adjust the sunrise time by specifying the current atmospheric air pressure. 😯 This, however, is completely out of the scope of this post. If you want to dig deeper, I recommend you to check out the official gcal manual. It's quite a read.
I'd be really excited to hear all the use cases for gcal one can come up with. Seems really suited for a TODO list manager or to never forget a birthday again. Maybe even as a ssh-synced shared company calendar app where every employee has its own resource file.
Let me hear your thoughts on this!
I hope you enjoyed my first post of the "Command Line Monday" series. Make sure to come back next Monday for a new post! If you are afraid that you might miss it you can go to the landing page and sign up for my newsletter to get a friendly reminder!
Update 2016-05-16
This post got unexpectedly quite some traction on Hacker News 😁 and therefore I just wanted to highlight a few of the interesting things people mentioned in the comments.
A lot of people thought that Monday should be the first day of the week and I completely agree! It's the official ISO 8601 standard after all. (And as you can read in Germany — You have failed the metric system, standards mean a lot to me!)
For convenience I use following script on my mac to alias cal
:
#! /usr/bin/env bash
gcal --starting-day=1 "$@"
This uses Monday as the first day of the week. Problem solved 😊
Bushra8 also mentioned a cool flag which displays the astronomical holidays. I.e. the next full moon or the next lunar eclipse.
$ gcal --holiday-list --astronomical-holidays
Eternal holiday list: The year 2016 is A leap year
New Moon 01:30 (Ast) - Sun, Jan 10th 2016 = -127 days
Waxing Half Moon 23:26 (Ast) - Sat, Jan 16th 2016 = -121 days
Full Moon 01:46 (Ast) - Sun, Jan 24th 2016 = -113 days
Waning Half Moon 03:28 (Ast) - Mon, Feb 1st 2016 = -105 days
New Moon 14:39 (Ast) - Mon, Feb 8th 2016 = -98 days
Waxing Half Moon 07:46 (Ast) - Mon, Feb 15th 2016 = -91 days
Full Moon 18:20 (Ast) - Mon, Feb 22nd 2016 = -84 days
Waning Half Moon 23:11 (Ast) - Tue, Mar 1st 2016 = -76 days
New Moon 01:54 (Ast) - Wed, Mar 9th 2016 = -68 days
Solar Eclipse/Total 01:57 (Ast) - Wed, Mar 9th 2016 = -68 days
Waxing Half Moon 17:03 (Ast) - Tue, Mar 15th 2016 = -62 days
Equinox Day 04:30 (Ast) - Sun, Mar 20th 2016 = -57 days
Full Moon 12:01 (Ast) - Wed, Mar 23rd 2016 = -54 days
Lunar Eclipse/Penumbral 11:47 (Ast) - Wed, Mar 23rd 2016 = -54 days
Waning Half Moon 15:17 (Ast) - Thu, Mar 31st 2016 = -46 days
…
If you have any comments, thoughts, or other feedback feel free to tweet me @AdrianSieber. Thanks for your help! 😊