@countrystatecity/timezones
v1.0.5
Published
Comprehensive timezone data with conversion utilities and iOS/Safari support
Maintainers
Readme
@countrystatecity/timezones
Comprehensive timezone data with conversion utilities and iOS/Safari support.
✨ Features
- 🌐 392 IANA Timezones: Complete timezone database
- 🗺️ 223 Countries: Timezones organized by country
- 🔄 Time Conversion: Convert between timezones easily
- ⏰ Current Time: Get current time in any timezone
- 📅 DST Support: Detect daylight saving time
- 📱 iOS Compatible: No stack overflow errors
- 🚀 Minimal Bundle: <20KB initial load with lazy loading
- 📝 TypeScript: Full type definitions included
- 🔧 Tree-Shakeable: Only bundle what you use
🎯 Why This Package?
The Problem with Existing Solutions
Many timezone packages have critical issues:
- 🔴 Large bundle sizes (include all data upfront)
- 🔴 iOS Safari compatibility issues
- 🔴 No lazy loading capabilities
- 🔴 Static imports force entire bundle inclusion
- 🔴 Outdated or incomplete timezone data
Our Solution
- ✅ Minimal bundle (<20KB initial)
- ✅ Dynamic imports & lazy loading
- ✅ iOS/Safari compatible
- ✅ Automatically updated from authoritative sources
- ✅ Tree-shakeable & code-splittable
- ✅ 390 IANA timezones with 99%+ population coverage
Bundle Size Advantage
Load only what you need:
- Initial import: ~5KB
- Load all timezones: +74KB
- Load one country's timezones: +0.3KB
- Typical usage: ~10KB total
Compared to traditional packages that bundle everything upfront (often 100KB+), this represents a 10x+ reduction in bundle size for typical use cases.
📦 Installation
npm install @countrystatecity/timezonesyarn add @countrystatecity/timezones🚀 Quick Start
import {
getTimezones,
getTimezonesByCountry,
convertTime,
getCurrentTime
} from '@countrystatecity/timezones';
// Get all timezones (~74KB - lazy loaded)
const timezones = await getTimezones();
console.log(timezones.length); // 392
// Get timezones for a specific country (~0.3KB per country)
const usTimezones = await getTimezonesByCountry('US');
console.log(usTimezones);
// [
// { zoneName: 'America/New_York', abbreviation: 'EST', ... },
// { zoneName: 'America/Chicago', abbreviation: 'CST', ... },
// ...
// ]
// Get current time in a timezone
const currentTime = await getCurrentTime('America/New_York');
console.log(currentTime); // "2025-10-18T08:30:00.000Z"
// Convert time between timezones
const converted = await convertTime(
'2025-10-18 14:00',
'America/New_York',
'Asia/Tokyo'
);
console.log(converted);
// {
// originalTime: "2025-10-18T14:00:00.000Z",
// fromTimezone: "America/New_York",
// convertedTime: "2025-10-19T04:00:00.000Z",
// toTimezone: "Asia/Tokyo",
// timeDifference: 14
// }📖 API Reference
Core Functions
getTimezones()
Get all available timezones.
const timezones = await getTimezones();
// Returns: ITimezone[]Bundle Impact: ~74KB
getTimezonesByCountry(countryCode: string)
Get timezones for a specific country.
const timezones = await getTimezonesByCountry('US');
// Returns: ITimezone[]Parameters:
countryCode- ISO 3166-1 alpha-2 country code (e.g., 'US', 'IN')
Bundle Impact: ~0.3KB per country
getTimezoneInfo(timezoneName: string)
Get detailed information about a timezone including current time.
const info = await getTimezoneInfo('America/New_York');
// Returns: ITimezoneInfo | nullReturns:
{
timezone: "America/New_York",
currentTime: "2025-10-18T08:30:00.000Z",
utcOffset: "UTC-05:00",
isDST: false,
gmtOffset: -18000
}getTimezoneAbbreviations()
Get all timezone abbreviations (PST, EST, etc.).
const abbreviations = await getTimezoneAbbreviations();
// Returns: ITimezoneAbbreviation[]Bundle Impact: ~5KB
getTimezonesByAbbreviation(abbreviation: string)
Find timezones by abbreviation.
const timezones = await getTimezonesByAbbreviation('EST');
// Returns: ITimezone[]Utility Functions
convertTime(time, fromTimezone, toTimezone)
Convert time from one timezone to another.
const result = await convertTime(
'2025-10-18 14:00',
'America/New_York',
'Europe/London'
);
// Returns: IConvertedTimeParameters:
time- Time to convert (ISO string or Date object)fromTimezone- Source timezone (IANA name)toTimezone- Target timezone (IANA name)
getCurrentTime(timezoneName: string)
Get current time in a specific timezone.
const time = await getCurrentTime('Asia/Tokyo');
// Returns: string (ISO format)isDaylightSaving(timezoneName: string, date?: Date)
Check if daylight saving time is active.
const isDST = await isDaylightSaving('America/New_York');
// Returns: booleanParameters:
timezoneName- IANA timezone namedate- Optional date to check (defaults to now)
getGMTOffset(timezoneName: string)
Get GMT/UTC offset in seconds.
const offset = await getGMTOffset('America/New_York');
// Returns: number (e.g., -18000 for UTC-05:00)formatGMTOffset(offsetSeconds: number)
Format GMT offset from seconds to string.
const formatted = formatGMTOffset(-18000);
// Returns: "UTC-05:00"isValidTimezone(timezoneName: string)
Validate if a timezone name is valid.
const isValid = await isValidTimezone('America/New_York');
// Returns: booleansearchTimezones(searchTerm: string)
Search timezones by name (partial match).
const results = await searchTimezones('america');
// Returns: ITimezone[]getUniqueAbbreviations()
Get all unique timezone abbreviations.
const abbreviations = await getUniqueAbbreviations();
// Returns: string[] (e.g., ['EST', 'PST', 'CST', ...])getTimezonesByOffset(offsetSeconds: number)
Get timezones by GMT offset.
const timezones = await getTimezonesByOffset(-18000); // UTC-05:00
// Returns: ITimezone[]📊 TypeScript Types
interface ITimezone {
zoneName: string; // "America/New_York"
countryCode: string; // "US"
abbreviation: string; // "EST"
gmtOffset: number; // -18000 (seconds)
gmtOffsetName: string; // "UTC-05:00"
tzName: string; // "Eastern Standard Time"
}
interface ITimezoneInfo {
timezone: string;
currentTime: string; // ISO string
utcOffset: string; // "UTC-05:00"
isDST: boolean;
gmtOffset: number;
}
interface ITimezoneAbbreviation {
abbreviation: string; // "EST"
name: string; // "Eastern Standard Time"
timezones: string[]; // ["America/New_York", ...]
}
interface IConvertedTime {
originalTime: string;
fromTimezone: string;
convertedTime: string;
toTimezone: string;
timeDifference: number; // hours
}🌍 Real-World Examples
Meeting Scheduler
import { convertTime, getTimezonesByCountry } from '@countrystatecity/timezones';
async function scheduleMeeting(localTime: string, attendeeCountries: string[]) {
const meetingTimes = [];
for (const countryCode of attendeeCountries) {
const timezones = await getTimezonesByCountry(countryCode);
const primaryTz = timezones[0];
const converted = await convertTime(
localTime,
'America/New_York',
primaryTz.zoneName
);
meetingTimes.push({
country: countryCode,
timezone: primaryTz.zoneName,
time: converted.convertedTime
});
}
return meetingTimes;
}
// Schedule 2 PM EST meeting for US, UK, and Japan
const times = await scheduleMeeting('2025-10-18 14:00', ['US', 'GB', 'JP']);World Clock
import { getTimezonesByCountry, getCurrentTime } from '@countrystatecity/timezones';
async function createWorldClock(countryCodes: string[]) {
const clocks = [];
for (const code of countryCodes) {
const timezones = await getTimezonesByCountry(code);
for (const tz of timezones) {
const currentTime = await getCurrentTime(tz.zoneName);
clocks.push({
location: tz.tzName,
timezone: tz.zoneName,
currentTime,
offset: tz.gmtOffsetName
});
}
}
return clocks;
}
const worldClock = await createWorldClock(['US', 'GB', 'IN', 'AU', 'JP']);DST Reminder
import { isDaylightSaving, getTimezonesByCountry } from '@countrystatecity/timezones';
async function checkDSTStatus(countryCode: string) {
const timezones = await getTimezonesByCountry(countryCode);
const dstStatus = [];
for (const tz of timezones) {
const isDST = await isDaylightSaving(tz.zoneName);
dstStatus.push({
timezone: tz.tzName,
isDST,
message: isDST
? '⚠️ Daylight Saving Time is active'
: '✓ Standard Time'
});
}
return dstStatus;
}📦 Bundle Size
| Action | Bundle Size | |--------|-------------| | Install package + import function | ~5KB | | Load all timezones | ~74KB | | Load timezones for one country | ~0.3KB | | Load abbreviations | ~5KB | | Typical usage | ~10KB |
📊 Data Coverage
- 390 IANA Timezones: Covers 90.7% of canonical IANA timezones
- 223 Countries: All countries with complete metadata
- 99%+ Population Coverage: Includes all major populated regions
What's Included
✅ All major countries and territories ✅ All business and residential timezones ✅ Complete DST information ✅ Historical timezone data
What's Not Included
❌ Antarctica research station timezones (11) ❌ Some small dependent territories (16) ❌ Some disputed/unrecognized territories (12)
See TIMEZONE_COVERAGE.md for detailed analysis.
Note: Timezone data is automatically sourced from the Countries States Cities Database and updates weekly. This ensures data accuracy while maintaining 99%+ real-world coverage.
🔄 CI/CD & Automation
Continuous Integration
Every push and PR automatically:
- ✅ Runs type checking with TypeScript
- ✅ Executes comprehensive test suite
- ✅ Builds the package
- ✅ Validates bundle sizes
- ✅ Tests iOS/Safari compatibility
Automated Data Updates
Weekly automated updates (Sundays at 00:00 UTC):
- 📥 Downloads latest timezone data from authoritative sources
- 🔄 Transforms into optimized structure
- 🧪 Runs full test suite
- 📝 Creates PR for review if changes detected
This ensures your application always has access to the most current timezone information without manual intervention.
Publishing
Automated publishing to NPM on version changes:
- 🔍 Detects version bumps in package.json
- 📦 Builds and tests before publishing
- 🚀 Publishes to NPM registry
- 🏷️ Creates GitHub release with changelog
🔗 Data Source
This package uses data from the open-source Countries States Cities Database, which is licensed under ODbL-1.0.
Why This Data Source?
- 📊 Authoritative: Maintained by the community with regular updates
- 🌍 Comprehensive: 250+ countries with complete timezone metadata
- 🔄 Always Current: Weekly automated updates ensure accuracy
- 🆓 Open Source: Free to use under ODbL-1.0 license
- 🧪 Verified: All data validated and tested before release
📄 License
This package and its data are licensed under the Open Database License (ODbL) v1.0. The data is sourced from the Countries States Cities Database which is also licensed under ODbL-1.0.
You are free to share, create, and adapt this database as long as you:
- Attribute: Credit the original sources
- Share-Alike: Distribute adaptations under the same license
- Keep Open: Don't use technical restrictions
🤝 Contributing
Contributions are welcome! We appreciate your help in making this package better.
How to Contribute
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
Reporting Issues
For data-related issues (incorrect timezone data, missing timezones, wrong offsets, etc.), please report them to the Countries States Cities Database repository, which is the authoritative source of data for this package.
For package issues (bugs, features, API improvements), please use this repository's issue tracker.
Development Setup
# Clone the repository
git clone https://github.com/dr5hn/countrystatecity-timezones.git
cd countrystatecity-timezones
# Install dependencies
npm install
# Run tests
npm test
# Build the package
npm run buildSee CONTRIBUTING.md for comprehensive contribution guidelines.
