It's a messy code but I've been working on a simple webpage that takes in a standardised format of string, which is a series of dates and a three letter code. I'm trying to create a single ics download file that adds each of these dates as individual full day events.
However, when I open the ics file it opens the calendar as normal but doesn't add any events. No errors anywhere.
The format of the dates that are entered into the text area look something like this:
Wed, 25 Jan 2023 ANI
Thu, 26 Jan 2023 ANI
Fri, 27 Jan 2023 ANI
the created iCal file in text looks similar to this:
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//bobbin v0.1//NONSGML iCal Writer//EN
CALSCALE:GREGORIAN
METHOD:PUBLISH
BEGIN:VEVENT
DTSTART:2023-01-30T00:00:00.000Z
DTEND:2023-01-30T23:59:59.999Z
DTSTAMP:2023-01-30T00:00:00.000Z
UID:0.78724cf20a484
CREATED:2022-12-30T22:08:08.107Z
DESCRIPTION:INI
SUMMARY:INI
END:VEVENT
BEGIN:VEVENT
DTSTART:2023-01-31T00:00:00.000Z
DTEND:2023-01-31T23:59:59.999Z
DTSTAMP:2023-01-31T00:00:00.000Z
UID:0.aa5407ba9b303
CREATED:2022-12-30T22:08:08.107Z
DESCRIPTION:INI
SUMMARY:INI
END:VEVENT
END:VCALENDAR
Here's the codebase:
function getStartDateString(str) {
const arr = str.split(', ');
const month = arr[1].split(' ')[1];
const monthNum = new Date(`${month} 1, 2022`).getMonth() + 1;
const dayOfMonth = arr[1].split(' ')[0];
const year = arr[1].split(' ')[2];
const date = `${year}-${monthNum}-${dayOfMonth}`;
const dateObj = new Date(date);
return dateObj.toISOString();
}
function getEndDateString(str) {
const arr = str.split(', ');
const month = arr[1].split(' ')[1];
const monthNum = new Date(`${month} 1, 2022`).getMonth() + 1;
const dayOfMonth = arr[1].split(' ')[0];
const year = arr[1].split(' ')[2];
const date = `${year}-${monthNum}-${dayOfMonth}`;
const dateObj = new Date(date);
dateObj.setHours(23, 59, 59, 999);
return dateObj.toISOString();
}
function createRandomICalUid() {
const randomNumber = Math.random();
const hexString = randomNumber.toString(16);
const uid = `${hexString}`;
return uid;
}
function downloadICal() {
const emailText = document.getElementById("rawRoster").value.split('\n')
const roster = emailText.filter(line => line.match(/^\w{3}, \d{2} \w{3} \d{4}/));
let rosterDays = ''
roster.forEach(day => {
const Startdate = getStartDateString(day);
const startDateObj = new Date(Startdate);
const endDate = getEndDateString(day);
const endDateObj = new Date(endDate);
const dtstamp = startDateObj.toISOString();
const dtend = endDateObj.toISOString();
let iCalEvent = `BEGIN:VEVENT
DTSTAMP:${dtstamp}
DTSTART:${dtstamp}
DTEND:${dtend}
UID:${createRandomICalUid()}
CREATED:${new Date().toISOString()}
DESCRIPTION:${day.slice(-3)}
SUMMARY:${day.slice(-3)}
LOCATION:Online
END:VEVENT
`
rosterDays += iCalEvent
});
const icalContent = `BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//bobbin v0.1//NONSGML iCal Writer//EN
CALSCALE:GREGORIAN
METHOD:PUBLISH
`+rosterDays+`END:VCALENDAR`
console.log(icalContent);
// Create a Blob from the iCalendar content
const blob = new Blob([icalContent], { type: 'text/calendar;charset=utf-8' });
// Create a link element to use for the download
const downloadLink = document.createElement('a');
downloadLink.download = 'duty.ics';
downloadLink.href = URL.createObjectURL(blob);
downloadLink.style.display = 'none';
// Add the link to the DOM and click it to trigger the download
document.body.appendChild(downloadLink);
downloadLink.click();
// Remove the link from the DOM
document.body.removeChild(downloadLink);
}
document.getElementById("downloadiCal").addEventListener("click", () => downloadICal())