npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@geoapify/iana-timezone-metadata

v1.0.0

Published

Compact IANA timezone metadata, aliases, UTC offsets, DST states, transitions, and country lookups.

Readme

IANA Timezone Metadata for TypeScript

@geoapify/iana-timezone-metadata

A dependency-free TypeScript and JavaScript library for fast IANA timezone lookup. Get canonical timezone identifiers and aliases, UTC offsets, DST states and transitions, abbreviations, country mappings, and bundled tzdb version information.

Features

  • canonical IANA timezone identifiers and aliases
  • standard, daylight-saving, and exceptional timezone states
  • formatted UTC offsets, offset seconds, and abbreviations
  • timezone state lookup at a specific instant
  • next-transition and transition-range lookup
  • canonical timezones associated with ISO country codes
  • bundled tzdb version, reference year, and supported transition range
  • immutable results and zero runtime dependencies

Installation

npm install @geoapify/iana-timezone-metadata

The package is ESM-only, includes TypeScript declarations, supports Node.js 18 and later, and can be used by browser applications through an ESM-compatible bundler.

Quick start

import {
  getNextTransition,
  getTimezone,
  getTimezoneState,
} from "@geoapify/iana-timezone-metadata";

const timezone = getTimezone("Europe/Nicosia");

console.log(timezone?.id);
// "Asia/Nicosia"

console.log(timezone?.standard);
// {
//   type: "standard",
//   utcOffset: "+02:00",
//   offsetSeconds: 7200,
//   abbreviation: "EET",
//   daylightSavingOffsetSeconds: 0
// }

const state = getTimezoneState(
  "Asia/Nicosia",
  new Date("2026-08-03T12:00:00Z"),
);

console.log(state?.abbreviation);
// "EEST"

const nextTransition = getNextTransition(
  "Asia/Nicosia",
  new Date("2026-08-03T12:00:00Z"),
);

console.log(nextTransition?.at);
// "2026-10-25T01:00:00Z"

API reference

| Function | Description | |---|---| | getTimezone() | Returns canonical TimezoneInfo metadata for an identifier or alias. | | getTimezoneState() | Returns the TimezoneState active at a TimezoneInstant. | | getNextTransition() | Returns the next TimezoneTransition after an instant. | | getTransitions() | Returns TimezoneTransition objects within a TransitionRange. | | getTimezonesForCountry() | Returns canonical TimezoneInfo objects associated with an ISO country code. | | resolveTimezone() | Resolves a canonical identifier or alias to its canonical identifier. | | isTimezone() | Reports whether an identifier is a known canonical timezone or alias. | | listTimezones() | Lists TimezoneInfo metadata for every canonical timezone. | | listTimezoneIds() | Lists canonical identifiers, optionally including aliases through ListTimezoneIdOptions. |

The databaseInfo constant exposes the bundled DatabaseInfo, including the tzdb version, reference year, and supported transition range.

getTimezone()

Returns reference-year metadata for a canonical IANA identifier or alias.

getTimezone(id: string): TimezoneInfo | undefined

Parameters

| Name | Type | Description | |---|---|---| | id | string | Canonical IANA timezone identifier or known alias. |

Returns

A frozen TimezoneInfo object, or undefined when the identifier is unknown. When an alias is supplied, the returned object's id is canonical.

Example

const canonical = getTimezone("Asia/Nicosia");
const alias = getTimezone("Europe/Nicosia");

console.log(alias?.id);
// "Asia/Nicosia"

console.log(alias === canonical);
// true

getTimezoneState()

Returns the state active in a timezone at a particular instant.

getTimezoneState(
  id: string,
  at?: TimezoneInstant,
): TimezoneState | undefined

Parameters

| Name | Type | Description | |---|---|---| | id | string | Canonical timezone identifier or alias. | | at | TimezoneInstant | Date or Unix milliseconds. Defaults to the current instant. |

Returns

The frozen TimezoneState active at at, or undefined for an unknown identifier.

Throws

RangeError when at is invalid or outside databaseInfo.transitionRange.

Example

const state = getTimezoneState(
  "Asia/Nicosia",
  Date.parse("2026-08-03T12:00:00Z"),
);

console.log(state);
// {
//   type: "daylightSaving",
//   utcOffset: "+03:00",
//   offsetSeconds: 10800,
//   abbreviation: "EEST",
//   daylightSavingOffsetSeconds: 3600
// }

getNextTransition()

Returns the first timezone transition strictly after an instant.

getNextTransition(
  id: string,
  after?: TimezoneInstant,
): TimezoneTransition | null | undefined

Parameters

| Name | Type | Description | |---|---|---| | id | string | Canonical timezone identifier or alias. | | after | TimezoneInstant | Date or Unix milliseconds. Defaults to the current instant. |

Returns

  • a TimezoneTransition when another transition exists;
  • null for a known timezone with no later transition in the supported range;
  • undefined for an unknown identifier.

Throws

RangeError when after is invalid or outside the supported transition range.

Example

const transition = getNextTransition(
  "Asia/Nicosia",
  Date.parse("2026-08-03T00:00:00Z"),
);

console.log(transition);
// {
//   at: "2026-10-25T01:00:00Z",
//   before: { type: "daylightSaving", abbreviation: "EEST", ... },
//   after: { type: "standard", abbreviation: "EET", ... },
//   offsetChangeSeconds: -3600,
//   kind: "daylight-end"
// }

getTransitions()

Returns all timezone transitions in a half-open interval: from is inclusive and to is exclusive.

getTransitions(
  id: string,
  range: TransitionRange,
): readonly TimezoneTransition[] | undefined

Parameters

| Name | Type | Description | |---|---|---| | id | string | Canonical timezone identifier or alias. | | range | TransitionRange | Inclusive start and exclusive end of the query. |

Returns

A frozen transition array, an empty array when the known timezone has no transitions in the interval, or undefined for an unknown identifier.

Throws

RangeError when the range is invalid or extends outside the supported transition range.

Example

const transitions = getTransitions("Asia/Nicosia", {
  from: Date.UTC(2026, 0, 1),
  to: Date.UTC(2027, 0, 1),
});

console.log(transitions?.map(({ at, kind }) => ({ at, kind })));
// [
//   { at: "2026-03-29T01:00:00Z", kind: "daylight-start" },
//   { at: "2026-10-25T01:00:00Z", kind: "daylight-end" }
// ]

getTimezonesForCountry()

Returns canonical timezone metadata associated with an ISO country code.

getTimezonesForCountry(countryCode: string): readonly TimezoneInfo[]

Parameters

| Name | Type | Description | |---|---|---| | countryCode | string | Case-insensitive ISO 3166-1 alpha-2 country code. |

Returns

A frozen array of canonical TimezoneInfo objects. An unknown country code returns an empty array. Associations come from IANA's zone tables.

Example

const timezones = getTimezonesForCountry("cy");

console.log(timezones.map(({ id }) => id));
// ["Asia/Famagusta", "Asia/Nicosia"]

resolveTimezone()

Resolves a canonical timezone identifier or alias to its canonical identifier.

resolveTimezone(id: string): string | undefined

Parameters

| Name | Type | Description | |---|---|---| | id | string | Canonical timezone identifier or alias. |

Returns

The canonical identifier, or undefined when id is unknown.

Example

resolveTimezone("Europe/Nicosia"); // "Asia/Nicosia"
resolveTimezone("Invalid/Zone");   // undefined

isTimezone()

Reports whether a string is a known canonical timezone identifier or alias.

isTimezone(id: string): boolean

Parameters

| Name | Type | Description | |---|---|---| | id | string | Canonical timezone identifier or alias. |

Returns

true when id is a known canonical identifier or alias; otherwise false.

Example

isTimezone("Asia/Nicosia");   // true
isTimezone("Europe/Nicosia"); // true
isTimezone("Invalid/Zone");   // false

listTimezones()

Lists metadata for every canonical timezone.

listTimezones(): readonly TimezoneInfo[]

Returns

The returned array and its timezone objects are frozen. Aliases do not create duplicate entries.

listTimezoneIds()

Lists sorted timezone identifier strings.

listTimezoneIds(
  options?: ListTimezoneIdOptions,
): readonly string[]

Parameters

| Name | Type | Description | |---|---|---| | options.includeAliases | boolean | Include aliases as well as canonical identifiers. Defaults to false. |

Returns

A frozen, sorted array of identifier strings.

Example

const canonicalIds = listTimezoneIds();
const allIds = listTimezoneIds({ includeAliases: true });

databaseInfo

Describes the bundled tzdb release and the generated data range.

const databaseInfo: DatabaseInfo
console.log(databaseInfo);
// {
//   tzdbVersion: "2026c",
//   referenceYear: 2026,
//   transitionRange: {
//     from: "2025-01-01T00:00:00Z",
//     until: "2032-01-01T00:00:00Z"
//   }
// }

The transition range is half-open: from is supported and until is not.

Types

TimezoneInfo

Reference-year metadata for one canonical timezone.

interface TimezoneInfo {
  readonly id: string;
  readonly aliases: readonly string[];
  readonly countryCodes: readonly string[];
  readonly location?: TimezoneLocation;
  readonly referenceYear: number;
  readonly standard: TimezoneState;
  readonly otherStates: readonly TimezoneState[];
  readonly hasDaylightSavingTime: boolean;
  readonly hasTransitions: boolean;
}

| Property | Description | |---|---| | id | Canonical IANA timezone identifier. | | aliases | Other identifiers resolving to this timezone. | | countryCodes | Associated ISO country codes from IANA zone tables. | | location | Representative location, not boundary geometry. | | referenceYear | Calendar year used to produce standard, otherStates, and the boolean flags. | | standard | Primary standard state, selected as the standard state active for the largest portion of the reference year. | | otherStates | Other states observed during the reference year. | | hasDaylightSavingTime | Whether a daylight-saving state occurs during the reference year. | | hasTransitions | Whether any state transition occurs during the reference year. |

TimezoneState

One distinct offset and abbreviation state.

interface TimezoneState {
  readonly type: TimezoneStateType;
  readonly utcOffset: string;
  readonly offsetSeconds: number;
  readonly abbreviation: string;
  readonly daylightSavingOffsetSeconds: number;
}

| Property | Description | |---|---| | type | State classification. | | utcOffset | Formatted offset such as "+05:30" or "-04:00". | | offsetSeconds | Signed offset east of UTC in seconds. | | abbreviation | tzdb abbreviation such as EET or EEST. | | daylightSavingOffsetSeconds | Adjustment relative to standard time. It may be negative or non-hourly. |

TimezoneStateType

type TimezoneStateType = "standard" | "daylightSaving" | "other";

other is reserved for states that cannot be accurately classified as standard or daylight-saving time.

TimezoneTransition

An exact change from one complete timezone state to another.

interface TimezoneTransition {
  readonly at: string;
  readonly before: TimezoneState;
  readonly after: TimezoneState;
  readonly offsetChangeSeconds: number;
  readonly kind: TimezoneTransitionKind;
}

| Property | Description | |---|---| | at | Transition instant as a UTC ISO 8601 string. | | before | State immediately before the transition. | | after | State at and immediately after the transition. | | offsetChangeSeconds | after.offsetSeconds - before.offsetSeconds. | | kind | Classification of the transition. |

TimezoneTransitionKind

type TimezoneTransitionKind =
  | "daylight-start"
  | "daylight-end"
  | "offset-change"
  | "designation-change";

An offset-change is not classified as DST. A designation-change changes an abbreviation or state designation without moving the clock.

TimezoneLocation

interface TimezoneLocation {
  readonly latitude: number;
  readonly longitude: number;
  readonly comments?: string;
}

The coordinates identify IANA's representative location for a timezone. They cannot be used to determine which timezone contains an arbitrary coordinate.

TimezoneInstant

type TimezoneInstant = Date | number;

Numbers are Unix timestamps in milliseconds, matching JavaScript Date.

TransitionRange

interface TransitionRange {
  readonly from: TimezoneInstant;
  readonly to: TimezoneInstant;
}

from is inclusive and to is exclusive.

ListTimezoneIdOptions

interface ListTimezoneIdOptions {
  readonly includeAliases?: boolean;
}

DatabaseInfo type

interface DatabaseInfo {
  readonly tzdbVersion: string;
  readonly referenceYear: number;
  readonly transitionRange: {
    readonly from: string;
    readonly until: string;
  };
}

Code samples

Get IANA timezone metadata

Read the standard state, other observed states, country associations, and aliases for a timezone:

import { getTimezone } from "@geoapify/iana-timezone-metadata";

const timezone = getTimezone("Asia/Nicosia");

if (!timezone) {
  throw new Error("Unknown timezone");
}

console.log({
  standardOffset: timezone.standard.utcOffset,
  otherStates: timezone.otherStates,
  usesDaylightSavingTime: timezone.hasDaylightSavingTime,
  countryCodes: timezone.countryCodes,
  aliases: timezone.aliases,
});

Get UTC offset and DST state for a date

Determine which offset and abbreviation apply at an exact point in time:

import { getTimezoneState } from "@geoapify/iana-timezone-metadata";

const state = getTimezoneState(
  "America/New_York",
  new Date("2026-07-01T12:00:00Z"),
);

console.log({
  offset: state?.utcOffset,
  abbreviation: state?.abbreviation,
  isDaylightSavingTime: state?.type === "daylightSaving",
});
// { offset: "-04:00", abbreviation: "EDT", isDaylightSavingTime: true }

List timezone and DST transitions

Build a schedule of clock changes within a half-open date range:

import { getTransitions } from "@geoapify/iana-timezone-metadata";

const transitions = getTransitions("Europe/Berlin", {
  from: Date.UTC(2026, 0, 1),
  to: Date.UTC(2027, 0, 1),
});

const schedule = transitions?.map((transition) => ({
  at: transition.at,
  from: transition.before.utcOffset,
  to: transition.after.utcOffset,
  kind: transition.kind,
}));

console.log(schedule);

List IANA timezones by country

Country codes are case-insensitive ISO 3166-1 alpha-2 codes:

import { getTimezonesForCountry } from "@geoapify/iana-timezone-metadata";

const timezones = getTimezonesForCountry("us");

console.log(timezones.map(({ id }) => id));

Resolve latitude and longitude to an IANA timezone

This package does not include timezone boundary geometry, so it cannot resolve latitude and longitude directly. First obtain an IANA timezone identifier with a geometry package or geocoding service, then pass that identifier to getTimezone() and the transition APIs.

Server-side lookup with geo-tz

For a local lookup in a Node.js application, geo-tz provides timezone boundary data:

npm install geo-tz
import { find } from "geo-tz";
import { getTimezone } from "@geoapify/iana-timezone-metadata";

const timezoneIds = find(47.650499, -122.35007);
const timezoneId = timezoneIds[0];
const timezone = timezoneId ? getTimezone(timezoneId) : undefined;

console.log(timezone?.id);
// "America/Los_Angeles"

find() returns an array because a coordinate can have multiple timezone candidates near borders or in disputed areas. Decide how to handle every candidate when that distinction matters to your application.

Get a timezone with Geoapify Reverse Geocoding

As an alternative, the Geoapify Reverse Geocoding API returns timezone information together with the address. Its timezone object already includes the IANA identifier, standard and daylight-saving offsets, and abbreviations. If those fields are sufficient, no additional timezone lookup is necessary.

Use timezone.name with this package when you also need its normalized metadata or transition APIs:

import { getTimezone } from "@geoapify/iana-timezone-metadata";

const params = new URLSearchParams({
  lat: "47.650499",
  lon: "-122.35007",
  format: "json",
  apiKey: "YOUR_GEOAPIFY_API_KEY",
});

const response = await fetch(
  `https://api.geoapify.com/v1/geocode/reverse?${params}`,
);

if (!response.ok) {
  throw new Error(`Reverse geocoding failed: ${response.status}`);
}

const data = await response.json();
const timezoneId = data.results[0]?.timezone?.name;
const timezone = timezoneId ? getTimezone(timezoneId) : undefined;

console.log(timezone?.id);
// "America/Los_Angeles"

Get timezone metadata from browser geolocation

In a browser, combine the Geolocation API with reverse geocoding to return a TimezoneInfo object for the user's current position:

import {
  getTimezone,
  type TimezoneInfo,
} from "@geoapify/iana-timezone-metadata";

function getCurrentPosition(): Promise<GeolocationPosition> {
  return new Promise((resolve, reject) => {
    navigator.geolocation.getCurrentPosition(resolve, reject);
  });
}

async function getCurrentTimezone(
  geoapifyApiKey: string,
): Promise<TimezoneInfo | undefined> {
  const { coords } = await getCurrentPosition();
  const params = new URLSearchParams({
    lat: String(coords.latitude),
    lon: String(coords.longitude),
    format: "json",
    apiKey: geoapifyApiKey,
  });

  const response = await fetch(
    `https://api.geoapify.com/v1/geocode/reverse?${params}`,
  );

  if (!response.ok) {
    throw new Error(`Reverse geocoding failed: ${response.status}`);
  }

  const data = await response.json() as {
    results?: Array<{ timezone?: { name?: string } }>;
  };
  const timezoneId = data.results?.[0]?.timezone?.name;

  return timezoneId ? getTimezone(timezoneId) : undefined;
}

const timezone = await getCurrentTimezone("YOUR_GEOAPIFY_API_KEY");

console.log(timezone?.id);
console.log(timezone?.standard.utcOffset);

Browser geolocation requires a secure context and the user's permission. When calling Geoapify directly from a browser, restrict the API key to your allowed origins.

Limitations

  • The package does not perform coordinate-to-timezone lookup and contains no timezone boundary polygons.
  • Locations are representative points supplied by IANA, not geographic coverage definitions.
  • It does not provide localized display names or Windows timezone identifiers.
  • Timezone abbreviations are not globally unique.
  • Country associations come from IANA's zone tables and do not imply exact geographic coverage.
  • Future transitions are predictions from the bundled tzdb release and can change when governments change their rules.
  • State and transition queries are limited to databaseInfo.transitionRange.

Data source and generation

The data is generated from the official IANA Time Zone Database. Runtime results use the bundled tzdb release and do not depend on the timezone database provided by the host's JavaScript Intl implementation.

Two generated artifacts are maintained:

  • data/iana-tzdb.json is a readable representation of source-level zone eras, rules, links, leap seconds, countries, and IANA zone tables.
  • src/generated/data.ts is the compact runtime artifact containing reference-year states and exact transitions.

The runtime transition range starts one year before the reference year and ends after five future years. Generation requires the IANA zic compiler on PATH, or its path can be supplied through TZDB_ZIC.

npm install
npm run generate -- --version 2026c --reference-year 2026
npm run check
npm run build

Use npm run generate without arguments to resolve IANA's current release and the current UTC calendar year automatically.

License

MIT © Geoapify. See LICENSE.