import { DateTime, Duration } from "luxon"; class Hashable { public get hash(): string { const str = JSON.stringify(this); // source: https://gist.github.com/hyamamoto/fd435505d29ebfa3d9716fd2be8d42f0?permalink_comment_id=2775538#gistcomment-2775538 let hash = 0; for (let i = 0; i < str.length; i++) hash = Math.imul(31, hash) + str.charCodeAt(i) | 0; return new Uint32Array([hash])[0].toString(36); } } export type EventJSONData = { summary: string; description: string; dtstart: string; dtend: string; }; export class EventData extends Hashable { public summary: string; public description: string; public start: DateTime; public duration: Duration; public constructor(json_data: EventJSONData) { super(); this.summary = json_data.summary; this.description = json_data.description; this.start = DateTime .fromISO(json_data.dtstart) .setLocale(navigator.language); const end = DateTime .fromISO(json_data.dtend) .setLocale(navigator.language); this.duration = end.diff(this.start); } } export type CalendarJSONData = { title: string; events: Array; }; export class CalendarData extends Hashable { public title: string; public events: Array; public constructor(json_data: CalendarJSONData) { super(); this.title = json_data.title this.events = []; for (const event_data of json_data.events) { this.events.push(new EventData(event_data)) } } }