CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-ical-js

Javascript parser for ics (rfc5545) and vcard (rfc6350) data

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

timezone.mddocs/

Timezone Management

Comprehensive timezone handling with support for VTIMEZONE components, UTC offset calculations, and timezone conversions. These classes enable proper timezone-aware date and time operations in compliance with RFC 5545.

Capabilities

Timezone Class

Timezone representation providing offset calculations and conversion utilities for iCalendar timezone handling.

/**
 * Timezone handling
 * @param data - Timezone initialization data
 */
class Timezone {
  constructor(data?: object);
  
  // Properties
  tzid: string;              // Timezone identifier
  component: Component;      // VTIMEZONE component
  expandedUntilYear: number; // Year until which timezone is expanded
  
  // Static methods
  static convert_time(tt: Time, from_zone: Timezone, to_zone: Timezone): Time;
  static fromData(aData: object): Timezone;
  static get utcTimezone(): Timezone;
  static get localTimezone(): Timezone;
  
  // Instance methods
  fromData(aData: object): void;
  utcOffset(tt: Time): number;
  toString(): string;
}

Usage Examples:

import ICAL from "ical.js";

// Get built-in timezones
const utc = ICAL.Timezone.utcTimezone;
const local = ICAL.Timezone.localTimezone;

console.log(utc.tzid);   // "UTC"
console.log(local.tzid); // System timezone ID

// Create timezone from VTIMEZONE component
const timezoneData = `BEGIN:VTIMEZONE
TZID:America/New_York
BEGIN:DAYLIGHT
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
TZNAME:EDT
DTSTART:20070311T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
TZNAME:EST
DTSTART:20071104T020000
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
END:STANDARD
END:VTIMEZONE`;

const tzComponent = ICAL.Component.fromString(timezoneData);
const nyTimezone = new ICAL.Timezone(tzComponent);

console.log(nyTimezone.tzid); // "America/New_York"

// Get UTC offset for specific time
const summerTime = ICAL.Time.fromString("20230715T120000");
const winterTime = ICAL.Time.fromString("20231215T120000");

const summerOffset = nyTimezone.utcOffset(summerTime); // -14400 (EDT: -4 hours)
const winterOffset = nyTimezone.utcOffset(winterTime); // -18000 (EST: -5 hours)

console.log(`Summer offset: ${summerOffset / 3600} hours`); // -4
console.log(`Winter offset: ${winterOffset / 3600} hours`); // -5

// Convert time between timezones
const utcTime = ICAL.Time.fromString("20230715T160000Z");
const nyTime = ICAL.Timezone.convert_time(utcTime, utc, nyTimezone);

console.log(`UTC: ${utcTime.toString()}`);    // "2023-07-15T16:00:00Z"
console.log(`NY: ${nyTime.toString()}`);      // "2023-07-15T12:00:00"

// Convert back to UTC
const backToUtc = ICAL.Timezone.convert_time(nyTime, nyTimezone, utc);
console.log(`Back to UTC: ${backToUtc.toString()}`); // "2023-07-15T16:00:00Z"

// Create timezone from data
const customTz = ICAL.Timezone.fromData({
  tzid: "Custom/Example",
  // Additional timezone data
});

TimezoneService

Singleton timezone registry for managing and accessing timezone definitions across the application.

/**
 * Timezone registry singleton
 */
const TimezoneService: {
  // Properties
  readonly count: number;  // Number of registered timezones
  
  // Methods
  reset(): void;
  has(tzid: string): boolean;
  get(tzid: string): Timezone | null;
  register(timezone: Timezone | Component, name?: string): void;
  remove(tzid: string): boolean;
};

Usage Examples:

import ICAL from "ical.js";

// Check available timezones
console.log(ICAL.TimezoneService.count); // Number of registered timezones

// Check if timezone exists
const hasNY = ICAL.TimezoneService.has("America/New_York");
console.log(hasNY); // true/false

// Get timezone by ID
const nyTimezone = ICAL.TimezoneService.get("America/New_York");
if (nyTimezone) {
  console.log(nyTimezone.tzid); // "America/New_York"
}

// Register new timezone from component
const timezoneComponent = ICAL.Component.fromString(`BEGIN:VTIMEZONE
TZID:Europe/London
BEGIN:DAYLIGHT
TZOFFSETFROM:+0000
TZOFFSETTO:+0100
TZNAME:BST
DTSTART:20070325T010000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:+0100
TZOFFSETTO:+0000
TZNAME:GMT
DTSTART:20071028T020000
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
END:STANDARD
END:VTIMEZONE`);

ICAL.TimezoneService.register(timezoneComponent);

// Verify registration
console.log(ICAL.TimezoneService.has("Europe/London")); // true
console.log(ICAL.TimezoneService.count); // Increased by 1

// Register timezone object with custom name
const customTimezone = new ICAL.Timezone(timezoneComponent);
ICAL.TimezoneService.register(customTimezone, "Custom/London");

// Remove timezone
const removed = ICAL.TimezoneService.remove("Custom/London");
console.log(removed); // true if successfully removed

// Reset to default timezones
ICAL.TimezoneService.reset();
console.log(ICAL.TimezoneService.count); // Back to default count

// Working with calendar components and timezones
const vcalendar = new ICAL.Component("vcalendar");
vcalendar.addSubcomponent(timezoneComponent);

// Register all timezones from a calendar
const allSubcomponents = vcalendar.getAllSubcomponents("vtimezone");
allSubcomponents.forEach(tzComponent => {
  ICAL.TimezoneService.register(tzComponent);
});

// Use timezone service with events
const event = new ICAL.Component("vevent");
event.addPropertyWithValue("dtstart", ICAL.Time.fromString("20230715T120000"));

const startProp = event.getFirstProperty("dtstart");
startProp.setParameter("tzid", "Europe/London");

// Get timezone for the event
const eventTimezone = ICAL.TimezoneService.get("Europe/London");
if (eventTimezone) {
  const startTime = startProp.getFirstValue();
  startTime.zone = eventTimezone;
  console.log(`Event starts at ${startTime.toString()} in ${eventTimezone.tzid}`);
}

UtcOffset Class

UTC offset representation for handling timezone offsets in hours and minutes.

/**
 * UTC offset representation
 * @param aData - Offset initialization data
 */
class UtcOffset {
  constructor(aData?: object);
  
  // Properties
  hours: number;    // Offset hours
  minutes: number;  // Offset minutes
  factor: number;   // Sign factor (+1 or -1)
  
  // Static methods
  static fromString(aString: string): UtcOffset;
  static fromSeconds(aSeconds: number): UtcOffset;
  
  // Instance methods
  clone(): UtcOffset;
  fromData(aData: object): void;
  fromSeconds(aSeconds: number): void;
  toSeconds(): number;
  compare(other: UtcOffset): number;
  toICALString(): string;
  toString(): string;
}

Usage Examples:

import ICAL from "ical.js";

// Create offset from string
const offset1 = ICAL.UtcOffset.fromString("-0500"); // -5 hours
const offset2 = ICAL.UtcOffset.fromString("+0230"); // +2 hours 30 minutes

console.log(offset1.hours);   // 5
console.log(offset1.minutes); // 0
console.log(offset1.factor);  // -1

console.log(offset2.hours);   // 2
console.log(offset2.minutes); // 30
console.log(offset2.factor);  // 1

// Create from seconds
const offset3 = ICAL.UtcOffset.fromSeconds(-18000); // -5 hours
console.log(offset3.toICALString()); // "-0500"

// Create from data
const offset4 = new ICAL.UtcOffset({
  hours: 3,
  minutes: 45,
  factor: 1
});

// Convert to seconds
console.log(offset1.toSeconds()); // -18000 (-5 hours)
console.log(offset2.toSeconds()); // 9000 (+2.5 hours)

// Compare offsets
console.log(offset1.compare(offset2)); // -1 (offset1 < offset2)
console.log(offset2.compare(offset1)); // 1 (offset2 > offset1)

// String representations
console.log(offset1.toICALString()); // "-0500"
console.log(offset1.toString());     // "-0500"

console.log(offset2.toICALString()); // "+0230"
console.log(offset2.toString());     // "+0230"

// Clone offset
const offsetCopy = offset1.clone();
console.log(offsetCopy.toICALString()); // "-0500"

// Modify offset
offset4.fromSeconds(7200); // Change to +2 hours
console.log(offset4.toICALString()); // "+0200"

// Working with timezone components
const vtimezone = new ICAL.Component("vtimezone");
vtimezone.addPropertyWithValue("tzid", "Custom/Offset");

const standard = new ICAL.Component("standard");
standard.addPropertyWithValue("tzoffsetfrom", offset2);
standard.addPropertyWithValue("tzoffsetto", offset1);
standard.addPropertyWithValue("dtstart", ICAL.Time.fromString("20231029T020000"));

vtimezone.addSubcomponent(standard);

// Extract offsets from properties
const offsetFromProp = standard.getFirstProperty("tzoffsetfrom");
const offsetToProp = standard.getFirstProperty("tzoffsetto");

console.log(offsetFromProp.getFirstValue().toICALString()); // "+0230"
console.log(offsetToProp.getFirstValue().toICALString());   // "-0500"

Timezone Helper Functions

import ICAL from "ical.js";

// Helper function to update timezones in a calendar
ICAL.helpers.updateTimezones(vcalendar);

// Example: Processing calendar with timezone definitions
const calendarString = `BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Example//Example//EN
BEGIN:VTIMEZONE
TZID:America/New_York
BEGIN:STANDARD
TZOFFSETFROM:-0400
TZOFFSETTO:-0500
TZNAME:EST
DTSTART:20071104T020000
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
END:STANDARD
BEGIN:DAYLIGHT
TZOFFSETFROM:-0500
TZOFFSETTO:-0400
TZNAME:EDT
DTSTART:20070311T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
UID:event@example.com
DTSTART;TZID=America/New_York:20230715T120000
DTEND;TZID=America/New_York:20230715T130000
SUMMARY:Meeting in NY timezone
END:VEVENT
END:VCALENDAR`;

const calendar = ICAL.Component.fromString(calendarString);

// Update timezones processes VTIMEZONE components
ICAL.helpers.updateTimezones(calendar);

// Now events can use the timezone
const event = calendar.getFirstSubcomponent("vevent");
const startTime = event.getFirstPropertyValue("dtstart");

console.log(startTime.zone.tzid); // "America/New_York"
console.log(startTime.toString()); // Local time in NY timezone

Common Timezone Operations

import ICAL from "ical.js";

// Convert event times to different timezones
function convertEventTimezone(event, targetTimezone) {
  const startTime = event.startDate;
  const endTime = event.endDate;
  
  const newStart = ICAL.Timezone.convert_time(startTime, startTime.zone, targetTimezone);
  const newEnd = ICAL.Timezone.convert_time(endTime, endTime.zone, targetTimezone);
  
  event.startDate = newStart;
  event.endDate = newEnd;
  
  return event;
}

// Get timezone offset for display
function getTimezoneDisplay(timezone, time) {
  const offset = timezone.utcOffset(time);
  const offsetObj = ICAL.UtcOffset.fromSeconds(offset);
  return `${timezone.tzid} (UTC${offsetObj.toString()})`;
}

// Check if time is in daylight saving time
function isDST(timezone, time) {
  // Compare with standard time offset
  const winterTime = new ICAL.Time({
    year: time.year,
    month: 12, // December
    day: 15,
    hour: 12
  });
  
  const currentOffset = timezone.utcOffset(time);
  const winterOffset = timezone.utcOffset(winterTime);
  
  return currentOffset !== winterOffset;
}

docs

components.md

index.md

parsing.md

recurrence.md

time-date.md

timezone.md

utilities.md

tile.json