or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

components.mdindex.mdparsing.mdrecurrence.mdtime-date.mdtimezone.mdutilities.md
tile.json

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;
}