Running WordPress? There’s now a WordPress-native version — WebCalendar for WordPress — that installs as a plugin instead of a separate PHP application, with full recurring-event support, iCal import/export, and a built-in holiday library. It’s free on WordPress.org, and there’s an overview here on k5n.us. The standalone PHP application on this page is still maintained and is not going away.
Table of Contents
About WebCalendar
WebCalendar is a PHP-based calendar application that can be configured as a single-user calendar, a multi-user calendar for groups of users, or as an event calendar viewable by visitors. MySQL/MariaDB, SQLite3, PostgreSQL, Oracle, DB2, Interbase, MS SQL Server, or ODBC is required. The version 1.9.X releases are still a little rough around the edges since these include an overhaul of the UI to use Bootstrap and jQuery and a complete rewrite of the web-based installer.
WebCalendar can be setup in a variety of ways, such as…
- A schedule management system for a single person
- A schedule management system for a group of people, allowing one or more assistants to manage the calendar of another user
- An events schedule that anyone can view, allowing visitors to submit new events
- A calendar server that can be viewed with iCalendar-compliant calendar applications like Mozilla Sunbird, Apple iCal or GNOME Evolution or RSS-enabled applications like Firefox, Thunderbird, RSSOwl, FeedDemon, or BlogExpress.
Overview of Features
- Multi-user support
- 30 supported languages: Basque, Bulgarian, Chinese-Big5, Chinese-GB2312, Czech, Danish, Dutch, English-US, Estonian, Finnish, French, Galician, German, Greek, Holo-Big5, Hungarian, Icelandic, Italian, Japanese, Korean, Norwegian, Polish, Portuguese_BR, Portuguese, Romanian, Russian, Spanish, Swedish, Turkish, Welsh (see current list of translations here)
- Web-based installer
- Auto-detect user’s language preference from browser settings
- View calendars by day, week, month or year
- View another user’s calendar
- View one or more users’ calendar via layers on top of your own calendar
- Add/Edit/Delete users
- Add/Edit/Delete events
- Repeating events including support for overriding or deleting (exceptions)
- Configurable custom event fields
- User-configurable preferences for colors, 12/24 time format, Sun/Mon week start
- Checks for scheduling conflicts
- Email reminders for upcoming events
- Email notifications for new/updated/deleted events
- Export events to iCalendar
- Import from iCalendar/ics format
- Optional general access (no login required) to allow calendar to be viewed by people without a login (useful for event calendars)
- Users can make their calendar available publicly to anyone with an iCalendar-compliant calendar program (such as Apple’s iCal, Mozilla Calendar or Sunbird)
- Publishing of free/busy schedules (part of the iCalendar standard)
- RSS support that puts a user’s calendar into RSS
- Subscribe to “remote” calendars (hosted elsewhere on the net) in either iCalendar or hCalendar formats (WebCalendar 1.1+)
- User authentication: Web-based, HTTP, LDAP or NIS
System Requirements
- PHP 8 or later
- PHP support and access to one of the following databases:
- SQLite
- MySQL/MariaDB
- Oracle
- Postgres
- IBM DB2
- Access to cron for Linux/Unix systems (to send out reminders)
Development Cost
The following metrics from Ohloh show how much it would have cost to commercially develop WebCalendar.
- Codebase Size: 138,588 lines
- Estimated Effort: 34 person-years
- Estimated Cost: $1,884,469
- (As of 11 August 2024)
Donations
If you’d like to help support the costs of developing, maintaining and supporting WebCalendar, please consider donating.
Developer Resources
- Github page for WebCalendar:
- Issues
- Pull requests
- Wiki
- Download the development code as a zip file
License
WebCalendar is available under the GNU General Public License, version 2.
For more information on this license:
Documentation
- System Administrator’s Guide
Introduction, installation instructions and FAQ - UPGRADING (WebCalendar 1.3.0)
Provides instruction on upgrading to version 1.3.7 from an older version - Database Design (WebCalendar 1.3.0)
Version 1.2.7 database schema
Most Recent Changes
Below are the most recent source code commits to github on the master branch.
- Merge pull request #792 from craigk5n/feat/audit-line-endings-noteby craigk5n on September 28, 2026 at 12:13 pm
Merge pull request #792 from craigk5n/feat/audit-line-endings-note feat: the audit says when a file differs only in line endings
- Merge pull request #791 from craigk5n/fix/788-zone-tab-crlfby craigk5n on September 28, 2026 at 12:11 pm
Merge pull request #791 from craigk5n/fix/788-zone-tab-crlf fix: zone.tab shipped with CRLF, so the audit called it modified (#788)
- feat: the audit says when a file differs only in line endingsby craigk5n on September 28, 2026 at 12:08 pm
feat: the audit says when a file differs only in line endings A file whose content matches MANIFEST.sha256 once CRLF and LF are normalised is now annotated, and the advice changes from “restore from release zip” to saying the content is otherwise identical and no action is needed. It is still reported. The file does differ from the bytes that were signed, and suppressing it would be the wrong trade for a page whose job is to notice that. What changes is that the page says which kind of difference it found. The prompt was #788: includes/zone.tab shipped with CRLF, an extraction converted it to LF, and establishing that took two hashes and a size comparison by hand. An unexplained “modified file” on an installation where nothing was touched is how administrators learn to ignore the page, and this will recur with any deployment pipeline that normalises text. Both directions are detected, because the conversion goes both ways: an extraction in text mode strips the CRs from a file shipped with CRLF, and an editor or checkout on Windows adds them to one shipped with LF. The manifest stores a hash rather than content, so the only way to ask is to convert the local copy and hash each candidate. Not softened anywhere it matters. Severity stays WARN and the kind stays MODIFIED. Content with a NUL byte is excluded, so a tampered GIF that happens to contain \r is never described as a line-ending difference. A change that alters content *and* line endings is not annotated. The check is capped at 8MB against the 1.5MB largest file in a release. Six mutations, each asserted written to disk before the verdict was believed: never annotate, always annotate, drop the binary guard, handle only one direction, stop branching in the hint, and have the table call the kind-only hint. All six caught — including “always annotate”, which is the one that would describe a webshell as harmless. The hint test lifts action_hint_for_file() out of security_audit.php and runs it with translate() stubbed, rather than asserting against its source. The first draft did match the source, which is the mistake behind the seven hollow guards repaired in v1.9.24 — a test satisfied by the prose in the function it is checking. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- fix: zone.tab shipped with CRLF, so the audit called it modified (#788)by craigk5n on September 28, 2026 at 11:56 am
fix: zone.tab shipped with CRLF, so the audit called it modified (#788) includes/zone.tab was committed with CRLF on all 407 lines. It was the only text file in the release doing so; .editorconfig has said end_of_line = lf for years, and the five other \r-bearing shipped files are binaries — a favicon, three GIFs and a TrueType font. Nothing read the file wrongly. display_tz_selection() does trim() then preg_split(‘/[\s,]+/’), so CRLF and LF produce the same 383 timezones; verified by parsing both forms and diffing the lists. The cost was to the signed manifest. MANIFEST.sha256 records the bytes that ship, so any deployment pipeline that normalises line endings — an extraction in text mode, a packaging step, an editor — leaves that one file disagreeing with its own manifest, and Reports > Security Audit reports it modified forever on an installation where nothing was modified. Diagnosed from the reporter’s two hashes rather than guessed: 2892d401… manifest, ZIP, v1.9.24 tag, v1.9.23 tag, working tree c20d18d3… the reporter’s file — exactly ours with the CRs stripped A substituted system zone.tab would differ in content, not solely in line endings, so the conversion is certain. Size alone shows it too: 17927 bytes shipped against 17520 converted, the 407 CRs. Reading straight out of the archive with `unzip -p` gives the manifest’s value, which is why extraction is the suspect rather than the build. Converting to LF makes the file hash c20d18d3… — the value the reporter already measured — so their installation will match the next release’s manifest. tests/ShippedLineEndingsTest.php fails the build when any file listed in release-files contains CRLF, treating a file as binary when it contains a NUL byte, the same heuristic git uses. All five shipped binaries contain NUL and no text file in the tree does. Four mutations, each asserted written to disk before the verdict: CRLF everywhere, a single CRLF line, one bare CR, and CRLF in a different shipped file. All four caught. This does not help existing v1.9.24 installations, whose manifest correctly describes CRLF bytes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- Merge pull request #787 from craigk5n/fix/release-skill-accuracyby craigk5n on September 26, 2026 at 4:25 pm
Merge pull request #787 from craigk5n/fix/release-skill-accuracy docs(release): correct an unverified outage claim, and the reverse case
Download Metrics
- Downloads via Github: 21321
- Downloads via SourceForge: 1417971
Related Links
- Standards
- Calendar client applications – You can use the applications to view events stored in WebCalendar if you enable its publishing settings.
- iCalendar/ics download sites – These sites contain calendars for holidays, sports teams schedules, music converts, etc. You can import these files into WebCalendar.
- iCalShare
- Apple iCal Library
- DateDex
- Project24: holiday and weather calendars