Whenever someone asked me about a calendar application, especially for the textmode, I always encouraged them to give pal a try. I always loved the looks of it, the interactive mode is helpful, it has HTML output format to inject the calendar into a webpage, mail output format for a daily reminder cronjob, and other useful features. I even created a file with the Austrian holidays for it which got included in the original project for the benefit of all its users.
If you haven't tried it yet and are looking for a calendar tool with support for very flexible recurring events and categories, this might be a good look.
I am still happy with pal, though someone recently suggested a different tool on IRC, and that was wyrd. From a quick glance it looked promising, so I started to dig into it. My first task was to convert the former mentioned pal file for the Austrian holidays into remind format. remind is the backend for wyrd, and its definition language seems to be extremely powerful. It though took me a while to figure out how to put in Easter date related events into it, the examples weren't really hinting me in the right direction. This is part of what I am using now: REM [trigger(easterdate(current())-47)] +6 TAG noweight MSG Faschingsdienstag %b
The look and view of wyrd is different to pal in several ways. Where the granularity of pal is a pure day view, wyrd scales in hours (or half, quarter thereof). Also, wyrd offers the possibility to color the days differently by busy level. Of course it's possible to exempt tasks from adding weight to a day. pal on the other hand is able to color events differently by category.
Decide yourself what you actually need, test it, and ... enjoy!