Back to Repositories

Validating Timezone and DST Handling in dayjs

This test suite validates timezone handling and DST (Daylight Saving Time) functionality in the dayjs library, comparing results with moment.js for consistency. The tests ensure accurate time calculations across different timezones and DST transitions.

Test Coverage Overview

The test suite provides comprehensive coverage of timezone-related operations including:
  • DST transitions and date arithmetic
  • UTC offset calculations
  • Time difference calculations across DST boundaries
  • UTC-specific operations and conversions
Key edge cases include timezone changes during DST transitions and cross-boundary date manipulations.

Implementation Analysis

The testing approach uses Jest’s expect assertions to compare dayjs operations with equivalent moment.js results. The implementation leverages timezone and UTC plugins, with particular attention to DST edge cases and offset calculations.

Tests utilize MockDate for consistent date manipulation and employ systematic verification of time-based operations across different timezone contexts.

Technical Details

Testing tools and configuration:
  • Jest as the testing framework
  • MockDate for date mocking
  • dayjs timezone and UTC plugins
  • moment.js for result verification
  • ISO string formats for consistent comparisons

Best Practices Demonstrated

The test suite exemplifies high-quality testing practices through:
  • Consistent test setup and teardown using beforeEach/afterEach
  • Comprehensive edge case coverage
  • Parallel validation against an established library
  • Isolated test cases with clear assertions
  • Systematic testing of related functionality groups

iamkun/dayjs

test/timezone.test.js

            
import MockDate from 'mockdate'
import moment from 'moment'
import dayjs from '../src'
import timezone from '../src/plugin/timezone'
import utc from '../src/plugin/utc'

dayjs.extend(utc)
dayjs.extend(timezone)

beforeEach(() => {
  MockDate.set(new Date())
})

afterEach(() => {
  MockDate.reset()
})

it('Add Time days (DST)', () => {
  // change timezone before running test
  // New Zealand (-720)
  expect(dayjs('2018-04-01').add(1, 'd').format()).toBe(moment('2018-04-01').add(1, 'd').format())
  expect(dayjs('2018-03-28').add(1, 'w').format()).toBe(moment('2018-03-28').add(1, 'w').format())
  // London (-60)
  expect(dayjs('2018-10-28').add(1, 'd').format()).toBe(moment('2018-10-28').add(1, 'd').format())
  expect(dayjs('2018-10-26').add(1, 'w').format()).toBe(moment('2018-10-26').add(1, 'w').format())
})

it('Utc Offset', () => {
  expect(dayjs().utcOffset()).toBe(moment().utcOffset())
})

it('Diff (DST)', () => {
  const day = '2018-10-28'
  const dayjsA = dayjs(day)
  const dayjsB = dayjs(day).add(-1000, 'days')
  const momentA = moment(day)
  const momentB = moment(day).add(-1000, 'days')
  const units = ['seconds', 'minutes', 'hours', 'days', 'weeks', 'months', 'quarters', 'years']
  units.forEach((unit) => {
    expect(dayjsA.diff(dayjsB, unit)).toBe(momentA.diff(momentB, unit))
    expect(dayjsA.diff(dayjsB, unit, true)).toBe(momentA.diff(momentB, unit, true))
  })
})

it('UTC add day in DST', () => {
  const testDate = '2019-03-10'
  const dayTest = dayjs(testDate)
    .utc()
    .startOf('day')
  const momentTest = moment(testDate)
    .utc()
    .startOf('day')
  expect(dayTest.add(1, 'day').format())
    .toBe(momentTest.clone().add(1, 'day').format())
  expect(dayTest.add(2, 'day').format())
    .toBe(momentTest.clone().add(2, 'day').format())
})

it('UTC and utcOffset', () => {
  const test1 = 1331449199000 // 2012/3/11 06:59:59 GMT+0000
  expect(dayjs(test1).utcOffset(-300).format())
    .toBe(moment(test1).utcOffset(-300).format())
  const test2 = '2000-01-01T06:31:00Z'
  expect(dayjs.utc(test2).utcOffset(-60).format())
    .toBe(moment.utc(test2).utcOffset(-60).format())

  // across DST, copied from utc.test.js#get utc offset with a number value
  const time = '2021-02-28 19:40:10'
  const hoursOffset = -8
  const daysJS = dayjs(time).utc().utcOffset(hoursOffset * 60, true)
  const momentJS = moment(time).utc(true).utcOffset(hoursOffset, true)

  expect(daysJS.toISOString()).toEqual(momentJS.toISOString())
})

it('UTC diff in DST', () => {
  // DST till 2020-10-25
  const day1 = dayjs.utc('20201023') // in DST
  const day2 = dayjs.utc('20201026')
  expect(day1.diff(day2, 'd'))
    .toBe(-3)
})