You can serve calendars in ICal format from your web application on-the fly or you can save it to the disk as an *.ical file and serve the static file. Then people can add it to their calendar application and see the events you list.
The modules in use:
This code generates two events. The first one has a beginning and ending date. The second one has a beginninng and a duration. It also includes a link to Zoom as the "location".
#!/usr/bin/perl
use strict;
use warnings;
use Data::ICal ();
use Data::ICal::Entry::Event ();
use DateTime ();
use DateTime::Format::ICal ();
use DateTime::Duration ();
my $calendar = Data::ICal->new;
my $now = DateTime->now;
{
my $begin = DateTime->new( year => 2021, month => 4, day => 5, hour => 15 );
my $end = DateTime->new( year => 2021, month => 4, day => 5, hour => 17 );
my $event = Data::ICal::Entry::Event->new;
$event->add_properties(
summary => 'Short title of the event',
description => "A longer description that can also have ebedded newlines.\nThen it can continue on a second and\nthird line.",
dtstart => DateTime::Format::ICal->format_datetime($begin),
location => 'The local coffee shop',
dtend => DateTime::Format::ICal->format_datetime($end),
dtstamp => DateTime::Format::ICal->format_datetime($now),
uid => DateTime::Format::ICal->format_datetime($begin) . '-short',
);
$calendar->add_entry($event);
}
{
my $begin = DateTime->new( year => 2021, month => 4, day => 6, hour => 6, time_zone => '+0200' );
my $duration = DateTime::Duration->new(hours => 3, minutes => 15);
my $event = Data::ICal::Entry::Event->new;
$event->add_properties(
summary => 'Another event',
description => "Description",
dtstart => DateTime::Format::ICal->format_datetime($begin),
location => 'https://zoom.us/',
duration => DateTime::Format::ICal->format_duration($duration),
dtstamp => DateTime::Format::ICal->format_datetime($now),
uid => DateTime::Format::ICal->format_datetime($begin) . '-other',
);
$calendar->add_entry($event);
}
print $calendar->as_string;
The output is this:
BEGIN:VCALENDAR
VERSION:2.0
PRODID:Data::ICal 0.24
BEGIN:VEVENT
DESCRIPTION:A longer description that can also have ebedded newlines.\nThen
it can continue on a second and\nthird line.
DTEND:20210405T170000
DTSTAMP:20210405T055524Z
DTSTART:20210405T150000
LOCATION:The local coffee shop
SUMMARY:Short title of the event
UID:20210405T150000-short
END:VEVENT
BEGIN:VEVENT
DESCRIPTION:Description
DTSTAMP:20210405T055524Z
DTSTART:20210406T040000Z
DURATION:+PT3H15M
LOCATION:https://zoom.us/
SUMMARY:Another event
UID:20210406T040000Z-other
END:VEVENT
END:VCALENDAR
Real world examples
For example the Perl Weekly newsletter has a calendar of Perl events based on the list of Perl events.