UNPKG

kk-date

Version:

kk-date is a fastest JavaScript library that parses, validations, manipulates, and displays dates and times. If you use Moment.js or Day.js already you can easily use kk-date.

371 lines (301 loc) 13 kB
const { describe, test, expect, beforeEach, beforeAll, afterAll } = require('@jest/globals'); const kk_date = require('../index'); describe('Cross-Platform Timezone Compatibility Tests', () => { beforeAll(() => { // Set global timezone to UTC for consistent test results across all systems kk_date.config({ timezone: 'UTC' }); }); afterAll(() => { // Reset to default timezone kk_date.config({ timezone: 'Europe/Istanbul' }); }); beforeEach(() => { // Ensure UTC timezone for each test kk_date.config({ timezone: 'UTC' }); }); describe('Environment Detection', () => { test('should detect environment correctly', () => { const isBrowser = typeof window !== 'undefined'; const isNode = typeof process !== 'undefined' && process.versions && process.versions.node; // Should be in Node.js environment for tests expect(isNode).toBeTruthy(); expect(isBrowser).toBeFalsy(); }); }); describe('Intl.DateTimeFormat Compatibility', () => { test('should use Intl.DateTimeFormat consistently', () => { const testDate = new Date('2024-07-15T12:00:00Z'); const timezone = 'America/New_York'; // Test that Intl.DateTimeFormat works const formatter = new Intl.DateTimeFormat('en-US', { timeZone: timezone, year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit', }); expect(() => formatter.format(testDate)).not.toThrow(); }); test('should handle timezone name formatting', () => { const testDate = new Date('2024-07-15T12:00:00Z'); const timezone = 'Europe/London'; const formatter = new Intl.DateTimeFormat('en-US', { timeZone: timezone, timeZoneName: 'short', }); const parts = formatter.formatToParts(testDate); const timezonePart = parts.find((part) => part.type === 'timeZoneName'); expect(timezonePart).toBeDefined(); expect(typeof timezonePart.value).toBe('string'); }); }); describe('Timezone Offset Calculation', () => { test('should calculate offsets consistently', () => { const testDate = new Date('2024-07-15T12:00:00Z'); const timezones = ['UTC', 'Europe/London', 'Europe/Paris', 'America/New_York', 'America/Los_Angeles', 'Asia/Tokyo']; // biome-ignore lint/complexity/noForEach: <explanation> timezones.forEach((timezone) => { expect(() => { const offset = kk_date.getTimezoneOffset(timezone, testDate); expect(typeof offset).toBe('number'); expect(offset).toBeGreaterThanOrEqual(-12 * 60 * 60 * 1000); // -12 hours expect(offset).toBeLessThanOrEqual(14 * 60 * 60 * 1000); // +14 hours }).not.toThrow(); }); }); test('should handle DST transitions correctly', () => { // Test DST detection for different seasons const winterOffset = kk_date.getTimezoneOffset('America/New_York', new Date('2024-01-15T12:00:00Z')); const summerOffset = kk_date.getTimezoneOffset('America/New_York', new Date('2024-07-15T12:00:00Z')); // Should be different due to DST expect(Math.abs(winterOffset - summerOffset)).toBeGreaterThan(0); expect(Math.abs(winterOffset - summerOffset)).toBeLessThanOrEqual(60 * 60 * 1000); // Max 1 hour difference }); }); describe('Cross-Platform Timezone Conversion', () => { test('should convert between timezones accurately', () => { const testCases = [ { input: '2024-07-15T12:00:00Z', from: 'UTC', to: 'America/New_York', expectedOffset: -4 * 60 * 60 * 1000, // EDT }, { input: '2024-01-15T12:00:00Z', from: 'UTC', to: 'America/New_York', expectedOffset: -5 * 60 * 60 * 1000, // EST }, { input: '2024-07-15T12:00:00Z', from: 'UTC', to: 'Europe/London', expectedOffset: 1 * 60 * 60 * 1000, // BST }, ]; // biome-ignore lint/complexity/noForEach: <explanation> testCases.forEach(({ input, from, to, expectedOffset }) => { const date = new Date(input); const converted = kk_date.convertToTimezone(date, to, from); // Calculate the actual offset const actualOffset = converted.getTime() - date.getTime(); // Allow for small differences due to DST rules expect(Math.abs(actualOffset - expectedOffset)).toBeLessThan(60 * 60 * 1000); }); }); test('should handle round-trip conversions', () => { const originalDate = new Date('2024-07-15T12:00:00Z'); const timezones = ['America/New_York', 'Europe/London', 'Asia/Tokyo', 'Australia/Sydney']; // biome-ignore lint/complexity/noForEach: <explanation> timezones.forEach((timezone) => { // Convert to timezone const converted = kk_date.convertToTimezone(originalDate, timezone, 'UTC'); // Convert back to UTC const backToUTC = kk_date.convertToTimezone(converted, 'UTC', timezone); // Should be the same time expect(backToUTC.getTime()).toBe(originalDate.getTime()); }); }); }); describe('DST Detection Accuracy', () => { test('should detect DST correctly for major timezones', () => { const summerDate = new Date('2024-07-15T12:00:00Z'); const winterDate = new Date('2024-01-15T12:00:00Z'); const timezonesWithDST = [ 'America/New_York', 'America/Chicago', 'America/Denver', 'America/Los_Angeles', 'Europe/London', 'Europe/Paris', 'Europe/Berlin', ]; const timezonesWithoutDST = ['UTC', 'Asia/Tokyo', 'Asia/Shanghai', 'Asia/Kolkata']; // Test timezones with DST // biome-ignore lint/complexity/noForEach: <explanation> timezonesWithDST.forEach((timezone) => { const summerDST = kk_date.isDST(timezone, summerDate); const winterDST = kk_date.isDST(timezone, winterDate); expect(summerDST).toBe(true); expect(winterDST).toBe(false); }); // Test timezones without DST // biome-ignore lint/complexity/noForEach: <explanation> timezonesWithoutDST.forEach((timezone) => { const summerDST = kk_date.isDST(timezone, summerDate); const winterDST = kk_date.isDST(timezone, winterDate); expect(summerDST).toBe(false); expect(winterDST).toBe(false); }); }); test('should handle DST transition dates', () => { // 2024 DST transitions for America/New_York const dstStart2024 = new Date('2024-03-10T07:00:00Z'); // 2 AM EST -> 3 AM EDT const dstEnd2024 = new Date('2024-11-03T06:00:00Z'); // 2 AM EDT -> 1 AM EST // Test DST start const beforeDSTStart = kk_date.isDST('America/New_York', new Date(dstStart2024.getTime() - 60000)); const afterDSTStart = kk_date.isDST('America/New_York', new Date(dstStart2024.getTime() + 60000)); expect(beforeDSTStart).toBe(false); expect(afterDSTStart).toBe(true); // Test DST end const beforeDSTEnd = kk_date.isDST('America/New_York', new Date(dstEnd2024.getTime() - 60000)); const afterDSTEnd = kk_date.isDST('America/New_York', new Date(dstEnd2024.getTime() + 60000)); expect(beforeDSTEnd).toBe(true); expect(afterDSTEnd).toBe(false); }); }); describe('Timezone Information Consistency', () => { test('should provide consistent timezone information', () => { const testDate = new Date('2024-07-15T12:00:00Z'); const timezone = 'America/New_York'; const info = kk_date.getTimezoneInfo(timezone, testDate); // Check all required properties expect(info).toHaveProperty('timezone', timezone); expect(info).toHaveProperty('offset'); expect(info).toHaveProperty('isDST'); expect(info).toHaveProperty('abbreviation'); expect(info).toHaveProperty('standardOffset'); expect(info).toHaveProperty('daylightOffset'); // Check data types expect(typeof info.offset).toBe('number'); expect(typeof info.isDST).toBe('boolean'); expect(typeof info.abbreviation).toBe('string'); expect(typeof info.standardOffset).toBe('number'); expect(typeof info.daylightOffset).toBe('number'); // Check logical consistency expect(info.isDST).toBe(true); // July should be DST expect(info.abbreviation).toBe('EDT'); // Eastern Daylight Time expect(Math.abs(info.offset - info.daylightOffset)).toBeLessThan(1000); // Should be close }); test('should handle edge case timezones', () => { const edgeCases = [ 'Pacific/Kiritimati', // UTC+14 'Pacific/Niue', // UTC-11 'Asia/Kolkata', // UTC+5:30 'Asia/Kathmandu', // UTC+5:45 ]; const testDate = new Date('2024-07-15T12:00:00Z'); // biome-ignore lint/complexity/noForEach: <explanation> edgeCases.forEach((timezone) => { expect(() => { const info = kk_date.getTimezoneInfo(timezone, testDate); expect(info.timezone).toBe(timezone); expect(typeof info.offset).toBe('number'); expect(typeof info.isDST).toBe('boolean'); }).not.toThrow(); }); }); }); describe('Performance and Memory', () => { test('should cache timezone calculations efficiently', () => { const testDate = new Date('2024-07-15T12:00:00Z'); const timezone = 'America/New_York'; // First call const start1 = performance.now(); const info1 = kk_date.getTimezoneInfo(timezone, testDate); const time1 = performance.now() - start1; // Second call (should be cached) const start2 = performance.now(); const info2 = kk_date.getTimezoneInfo(timezone, testDate); const time2 = performance.now() - start2; // Results should be identical expect(info1).toEqual(info2); // Both calls should complete successfully expect(time1).toBeGreaterThan(0); expect(time2).toBeGreaterThan(0); }); test('should handle multiple timezone operations without memory leaks', () => { const timezones = ['UTC', 'Europe/London', 'America/New_York', 'Asia/Tokyo', 'Europe/Paris', 'America/Los_Angeles', 'Australia/Sydney']; const iterations = 1000; const startMemory = process.memoryUsage().heapUsed; for (let i = 0; i < iterations; i++) { const testDate = new Date('2024-07-15T12:00:00Z'); // biome-ignore lint/complexity/noForEach: <explanation> timezones.forEach((timezone) => { kk_date.getTimezoneInfo(timezone, testDate); kk_date.isDST(timezone, testDate); kk_date.getTimezoneAbbreviation(timezone, testDate); }); } const endMemory = process.memoryUsage().heapUsed; const memoryIncrease = endMemory - startMemory; // Memory increase should be reasonable (less than 20MB) expect(memoryIncrease).toBeLessThan(20 * 1024 * 1024); }); }); describe('Error Handling', () => { test('should handle invalid timezones gracefully', () => { const invalidTimezones = ['', 'Invalid/Timezone', 'Not/A/Timezone']; // biome-ignore lint/complexity/noForEach: <explanation> invalidTimezones.forEach((timezone) => { expect(() => kk_date.checkTimezone(timezone)).toThrow(); expect(() => kk_date.getTimezoneInfo(timezone)).toThrow(); }); }); test('should handle null and undefined inputs', () => { expect(() => kk_date.getTimezoneInfo(null)).toThrow(); }); test('should handle invalid dates', () => { const invalidDates = [new Date('invalid'), new Date(NaN)]; // biome-ignore lint/complexity/noForEach: <explanation> invalidDates.forEach((date) => { expect(() => kk_date.getTimezoneInfo('UTC', date)).toThrow(); }); }); }); describe('Real-World Scenarios', () => { test('should handle international flight scenarios', () => { // Flight from New York to Tokyo const departureTime = new Date('2024-07-15T10:00:00Z'); // 10 AM UTC const flightDuration = 14 * 60 * 60 * 1000; // 14 hours // Departure time in New York (UTC-4 in July due to DST) const nyDeparture = kk_date.convertToTimezone(departureTime, 'America/New_York', 'UTC'); // Arrival time in Tokyo (UTC+9) const arrivalTime = new Date(departureTime.getTime() + flightDuration); const tokyoArrival = kk_date.convertToTimezone(arrivalTime, 'Asia/Tokyo', 'UTC'); // With UTC global timezone, results should be consistent across systems // New York departure: 10:00 UTC = 06:00 EDT (UTC-4) expect(nyDeparture.getUTCHours()).toBe(6); // 6 AM in New York // Tokyo arrival: 24:00 UTC = 09:00 JST (UTC+9) next day expect(tokyoArrival.getUTCHours()).toBe(9); // 9 AM in Tokyo }); test('should handle business meeting across timezones', () => { // Meeting at 2 PM London time (UTC+1 in July due to BST) const londonTime = new Date('2024-07-15T14:00:00Z'); const londonMeeting = kk_date.convertToTimezone(londonTime, 'Europe/London', 'UTC'); // Convert to other timezones const nyTime = kk_date.convertToTimezone(londonTime, 'America/New_York', 'UTC'); const tokyoTime = kk_date.convertToTimezone(londonTime, 'Asia/Tokyo', 'UTC'); // With UTC global timezone, results should be consistent across systems // London: 14:00 UTC = 15:00 BST (UTC+1) expect(londonMeeting.getUTCHours()).toBe(15); // 3 PM in London // New York: 14:00 UTC = 10:00 EDT (UTC-4) expect(nyTime.getUTCHours()).toBe(10); // 10 AM in New York // Tokyo: 14:00 UTC = 23:00 JST (UTC+9) expect(tokyoTime.getUTCHours()).toBe(23); // 11 PM in Tokyo }); }); });