Skip to content

DateUtils.addHoursWithDST() double-adjusts for DST transitions #110

@thedhanawada

Description

@thedhanawada

Bug Description

DateUtils.addHoursWithDST() at lines 510-526 adds hours via UTC milliseconds (which already handles DST correctly since it operates on absolute time), then applies an ADDITIONAL DST offset adjustment. This double-corrects, producing times that are off by the DST delta (typically 1 hour).

Impact

  • Adding hours across a DST boundary produces times that are off by 1 hour
  • Spring forward: time is 1 hour too late; Fall back: time is 1 hour too early
  • Affects all timezone-aware hour additions (e.g., shifting events, calculating end times)

Code Location

// DateUtils.js:510-526
static addHoursWithDST(date, hours, timeZone) {
  const result = new Date(date);
  const originalOffset = DateUtils.getTimezoneOffset(date, timeZone);

  // Add hours — this already works correctly in UTC millis
  result.setTime(result.getTime() + hours * 60 * 60 * 1000);

  // REDUNDANT: This second adjustment double-corrects
  const newOffset = DateUtils.getTimezoneOffset(result, timeZone);
  if (originalOffset \!== newOffset) {
    const dstAdjustment = (newOffset - originalOffset) * 60000;
    result.setTime(result.getTime() + dstAdjustment);
  }

  return result;
}

Fix

Remove the DST adjustment block entirely. UTC millisecond arithmetic is DST-agnostic by design:

static addHoursWithDST(date, hours, timeZone) {
  const result = new Date(date);
  result.setTime(result.getTime() + hours * 60 * 60 * 1000);
  return result;
}

If the intent is to add "wall clock hours" (preserving the local time appearance), the adjustment direction is also wrong — it should subtract the delta, not add it. But for a calendar library, UTC-based addition is almost always the correct behavior.

Files

  • core/calendar/DateUtils.js:510-526

Metadata

Metadata

Assignees

No one assigned

    Labels

    phase:0-foundationImmediate fixes and test infrastructurepriority:criticalMust fix before any releasetype:bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions