Immutable date wrapper library for JavaScript with comprehensive date/time manipulation, timezone support, and internationalization capabilities.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Luxon provides comprehensive timezone support through multiple Zone implementations. The Zone system handles timezone conversions, offset calculations, and timezone name resolution.
The base class that all timezone implementations extend.
/**
* Abstract base class for all timezone implementations
*/
abstract class Zone {
/** Type identifier for the zone implementation */
abstract type: string;
/** Zone name or identifier */
abstract name: string;
/** IANA timezone name (defaults to name) */
get ianaName(): string;
/** Whether the zone has a fixed offset (no DST) */
abstract isUniversal: boolean;
/** Whether the zone is valid */
abstract isValid: boolean;
/**
* Get timezone offset name at specific timestamp
* @param ts - Timestamp in milliseconds
* @param opts - Options including format and locale
*/
abstract offsetName(ts: number, opts: {format?: string, locale?: string}): string;
/**
* Format offset as string
* @param ts - Timestamp in milliseconds
* @param format - Format type ('short', 'narrow', 'long')
*/
abstract formatOffset(ts: number, format: string): string;
/**
* Get offset in minutes at specific timestamp
* @param ts - Timestamp in milliseconds
*/
abstract offset(ts: number): number;
/**
* Check equality with another zone
* @param otherZone - Zone to compare
*/
abstract equals(otherZone: Zone): boolean;
}Zone implementation for fixed UTC offsets.
/**
* Timezone with fixed offset from UTC (no daylight saving time)
*/
class FixedOffsetZone extends Zone {
type: "fixed";
isUniversal: true;
isValid: true;
/**
* UTC timezone singleton
*/
static utcInstance: FixedOffsetZone;
/**
* Get or create FixedOffsetZone instance
* @param offset - Offset in minutes from UTC
*/
static instance(offset: number): FixedOffsetZone;
/**
* Parse UTC offset string to create FixedOffsetZone
* @param s - Offset string (e.g., "+05:00", "-0700", "Z")
*/
static parseSpecifier(s: string): FixedOffsetZone;
name: string; // e.g., "UTC", "UTC+5", "UTC-7"
ianaName: string; // e.g., "Etc/UTC", "Etc/GMT-5"
/**
* Returns zone name
*/
offsetName(): string;
/**
* Format offset string
* @param ts - Timestamp (unused for fixed zones)
* @param format - Format type
*/
formatOffset(ts: number, format: string): string;
/**
* Returns the fixed offset
* @param ts - Timestamp (unused for fixed zones)
*/
offset(ts: number): number;
/**
* Check equality with another zone
* @param otherZone - Zone to compare
*/
equals(otherZone: Zone): boolean;
}Zone implementation using the IANA timezone database.
/**
* Timezone using IANA timezone database (e.g., "America/New_York")
*/
class IANAZone extends Zone {
type: "iana";
isUniversal: false;
/**
* Create or retrieve cached IANA zone
* @param name - IANA timezone name
*/
static create(name: string): IANAZone;
/**
* Reset internal cache
*/
static resetCache(): void;
/**
* Check if timezone name exists in IANA database
* @param zone - Timezone name to check
*/
static isValidZone(zone: string): boolean;
name: string; // IANA timezone name
isValid: boolean; // Whether timezone exists
/**
* Get timezone offset name at timestamp
* @param ts - Timestamp in milliseconds
* @param opts - Options including format and locale
*/
offsetName(ts: number, opts: {format?: string, locale?: string}): string;
/**
* Format offset as string
* @param ts - Timestamp in milliseconds
* @param format - Format type
*/
formatOffset(ts: number, format: string): string;
/**
* Get offset in minutes at timestamp (accounts for DST)
* @param ts - Timestamp in milliseconds
*/
offset(ts: number): number;
/**
* Check equality with another zone
* @param otherZone - Zone to compare
*/
equals(otherZone: Zone): boolean;
}Zone implementation using the system's local timezone.
/**
* System/local timezone implementation
*/
class SystemZone extends Zone {
type: "system";
isUniversal: false;
isValid: true;
/**
* Singleton system zone instance
*/
static instance: SystemZone;
name: string; // System timezone name (detected)
/**
* Get timezone offset name at timestamp
* @param ts - Timestamp in milliseconds
* @param opts - Options including format and locale
*/
offsetName(ts: number, opts: {format?: string, locale?: string}): string;
/**
* Format offset as string
* @param ts - Timestamp in milliseconds
* @param format - Format type
*/
formatOffset(ts: number, format: string): string;
/**
* Get system offset in minutes at timestamp
* @param ts - Timestamp in milliseconds
*/
offset(ts: number): number;
/**
* Check equality with another zone
* @param otherZone - Zone to compare
*/
equals(otherZone: Zone): boolean;
}Zone implementation for invalid timezone specifications.
/**
* Invalid timezone implementation (for error handling)
*/
class InvalidZone extends Zone {
type: "invalid";
isUniversal: false;
isValid: false;
name: string; // The invalid timezone name that was attempted
/**
* Always returns null
*/
offsetName(): null;
/**
* Always returns empty string
* @param ts - Timestamp (unused)
* @param format - Format (unused)
*/
formatOffset(ts: number, format: string): string;
/**
* Always returns NaN
* @param ts - Timestamp (unused)
*/
offset(ts: number): number;
/**
* Always returns false
* @param otherZone - Zone to compare (unused)
*/
equals(otherZone: Zone): boolean;
}import { DateTime, FixedOffsetZone, IANAZone, SystemZone } from "luxon";
// Working with fixed offset zones
const utc = FixedOffsetZone.utcInstance;
const est = FixedOffsetZone.instance(-300); // UTC-5 (300 minutes behind)
const parsedOffset = FixedOffsetZone.parseSpecifier("+05:30");
console.log(utc.name); // "UTC"
console.log(est.name); // "UTC-5"
console.log(est.offset()); // -300
// Working with IANA zones
const nyZone = IANAZone.create("America/New_York");
const tokyoZone = IANAZone.create("Asia/Tokyo");
const invalidZone = IANAZone.create("Invalid/Zone");
console.log(nyZone.isValid); // true
console.log(invalidZone.isValid); // false
// Check if timezone exists
console.log(IANAZone.isValidZone("America/New_York")); // true
console.log(IANAZone.isValidZone("America/Invalid")); // false
// Using zones with DateTime
const dt = DateTime.now();
const dtInNY = dt.setZone("America/New_York");
const dtInTokyo = dt.setZone(tokyoZone);
const dtInEST = dt.setZone(est);
// System timezone
const systemZone = SystemZone.instance;
console.log(systemZone.name); // System-detected timezone name
// Timezone information at specific times
const timestamp = DateTime.local(2023, 7, 15).toMillis(); // Summer
const winterTimestamp = DateTime.local(2023, 1, 15).toMillis(); // Winter
// DST affects IANA zones but not fixed offset zones
console.log(nyZone.offset(timestamp)); // e.g., -240 (EDT)
console.log(nyZone.offset(winterTimestamp)); // e.g., -300 (EST)
console.log(est.offset(timestamp)); // -300 (always)
console.log(est.offset(winterTimestamp)); // -300 (always)
// Offset names
console.log(nyZone.offsetName(timestamp, { format: 'short' })); // "EDT"
console.log(nyZone.offsetName(winterTimestamp, { format: 'short' })); // "EST"
console.log(nyZone.offsetName(timestamp, { format: 'long' })); // "Eastern Daylight Time"
// Format offsets
console.log(nyZone.formatOffset(timestamp, 'short')); // "-04:00"
console.log(nyZone.formatOffset(winterTimestamp, 'short')); // "-05:00"import { Info, Settings, IANAZone } from "luxon";
// Check if timezone has daylight saving time
console.log(Info.hasDST("America/New_York")); // true
console.log(Info.hasDST("America/Phoenix")); // false
console.log(Info.hasDST("UTC")); // false
// Validate timezone names
console.log(Info.isValidIANAZone("America/New_York")); // true
console.log(Info.isValidIANAZone("Invalid/Zone")); // false
// Convert various inputs to Zone instances
const zone1 = Info.normalizeZone("America/New_York"); // IANAZone
const zone2 = Info.normalizeZone(-300); // FixedOffsetZone
const zone3 = Info.normalizeZone("system"); // SystemZone
// Set default timezone
Settings.defaultZone = "America/New_York";
Settings.defaultZone = IANAZone.create("Asia/Tokyo");
Settings.defaultZone = FixedOffsetZone.instance(330); // UTC+5:30// UTC operations
const utcNow = DateTime.utc();
const utcZone = FixedOffsetZone.utcInstance;
// Local timezone operations
const localNow = DateTime.local();
const systemZone = SystemZone.instance;
// Specific timezone operations
const nyTime = DateTime.now().setZone("America/New_York");
const londonTime = DateTime.now().setZone("Europe/London");
// Fixed offset without DST
const alwaysUTCMinus5 = DateTime.now().setZone(FixedOffsetZone.instance(-300));
// Converting between timezones
const meeting = DateTime.local(2023, 6, 15, 14, 0); // 2 PM local
const meetingInNY = meeting.setZone("America/New_York");
const meetingInTokyo = meeting.setZone("Asia/Tokyo");
console.log(`Local: ${meeting.toFormat('HH:mm')}`);
console.log(`NY: ${meetingInNY.toFormat('HH:mm')}`);
console.log(`Tokyo: ${meetingInTokyo.toFormat('HH:mm')}`);