Skip to content

🐛 Bug: Custom Weekly Granularities with Offsets Produce Inconsistent Results Due to Year Start Origin #10085

@divij123

Description

@divij123

Describe the bug
Custom weekly granularities with offsets produce inconsistent and unpredictable results because timeSeriesFromCustomInterval uses startOf('year') as the default origin. This causes week boundaries to shift unexpectedly based on what day of the week January 1st falls on, making it impossible to create reliable Tuesday/Wednesday/Thursday-based weekly intervals.

To Reproduce
Steps to reproduce the behavior:

  1. Create a custom granularity with a weekly interval and offset to shift from Monday to Tuesday
  2. Query data using this granularity across different calendar years
  3. Compare the resulting week boundaries between years
  4. Observe that the same configuration produces different weekday alignments
// In cube schema, time dimension with custom granularity
granularities: {
  tuesday_week: {
    title: "Tuesday Week",
    interval: "1 week",
    offset: `-6 days`
  }
}

Expected behavior
The tuesday_week granularity should consistently produce Tuesday-based week boundaries regardless of the calendar year:
2025-09-23T00:00:00.000 (Tuesday)
2025-09-30T00:00:00.000 (Tuesday)
2025-10-07T00:00:00.000 (Tuesday)
2025-10-14T00:00:00.000 (Tuesday)
2025-10-21T00:00:00.000 (Tuesday)
This behavior should be consistent across all years.

Screenshots
If applicable, add screenshots to help explain your problem.

Minimally reproducible Cube Schema
N/A

Version:
1.3.83

Additional context
Root Cause:
The issue is in packages/cubejs-client-core/src/time.ts (line ~214) and packages/cubejs-backend-shared/src/time.ts where the default origin is set to:

let origin = granularity.origin ? internalDayjs(granularity.origin) : internalDayjs().startOf('year');

Since January 1st can fall on any weekday, the offset calculations produce different results in different years:
2025: Jan 1 = Wednesday → offset "1 day" creates Thursday weeks (not Tuesday)
2024: Jan 1 = Monday → offset "1 day" creates Tuesday weeks (correct by accident)
2026: Jan 1 = Thursday → offset "1 day" creates Friday weeks (not Tuesday)
Proposed Fix:
Replace year start with first Monday of the year as default origin:

let origin = granularity.origin ? internalDayjs(granularity.origin) : getFirstMondayOfYear();

function getFirstMondayOfYear(): dayjs.Dayjs {
  const yearStart = internalDayjs().startOf('year');
  const jan1Weekday = yearStart.isoWeekday();
  const daysToFirstMonday = jan1Weekday === 1 ? 0 : (8 - jan1Weekday);
  return yearStart.add(daysToFirstMonday, 'day');
}

Secondary Issue:
Version 1.3.83 also introduced ESM build import errors that prevent proper module resolution in ES module environments.

Impact:
This bug makes it impossible to create reliable fiscal weeks, business reporting periods, or any custom weekly intervals that need to consistently start on specific weekdays other than Monday.

Metadata

Metadata

Assignees

Labels

data modelingquestionThe issue is a question. Please use Stack Overflow for questions.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions