@@ -7,6 +7,21 @@ export const DEFAULT_PREDICTION_POINTS = 4
77// Bucket boundaries (UTC)
88// ---------------------------------------------------------------------------
99
10+ const DAY_MS = 86_400_000
11+
12+ function getUtcDayStart ( ts : number ) : number {
13+ const d = new Date ( ts )
14+ return Date . UTC ( d . getUTCFullYear ( ) , d . getUTCMonth ( ) , d . getUTCDate ( ) )
15+ }
16+
17+ // Monday-based week start in UTC
18+ function getWeeklyBucketStartUtc ( ts : number ) : number {
19+ const dayStart = getUtcDayStart ( ts )
20+ const day = new Date ( dayStart ) . getUTCDay ( )
21+ const diffFromMonday = ( day + 6 ) % 7
22+ return dayStart - diffFromMonday * DAY_MS
23+ }
24+
1025function clampRatio ( value : number ) : number {
1126 if ( value < 0 ) return 0
1227 if ( value > 1 ) return 1
@@ -26,6 +41,7 @@ export function getBucketStartUtc(ts: number, g: ChartTimeGranularity): number {
2641 const d = new Date ( ts )
2742 if ( g === 'yearly' ) return Date . UTC ( d . getUTCFullYear ( ) , 0 , 1 )
2843 if ( g === 'monthly' ) return Date . UTC ( d . getUTCFullYear ( ) , d . getUTCMonth ( ) , 1 )
44+ if ( g === 'weekly' ) return getWeeklyBucketStartUtc ( ts )
2945 return Date . UTC ( d . getUTCFullYear ( ) , d . getUTCMonth ( ) , d . getUTCDate ( ) )
3046}
3147
@@ -34,7 +50,7 @@ export function getBucketEndUtc(ts: number, g: ChartTimeGranularity): number {
3450 const d = new Date ( ts )
3551 if ( g === 'yearly' ) return Date . UTC ( d . getUTCFullYear ( ) + 1 , 0 , 1 )
3652 if ( g === 'monthly' ) return Date . UTC ( d . getUTCFullYear ( ) , d . getUTCMonth ( ) + 1 , 1 )
37- if ( g === 'weekly' ) return getBucketStartUtc ( ts , 'daily' ) + 7 * 86_400_000
53+ if ( g === 'weekly' ) return getWeeklyBucketStartUtc ( ts ) + 7 * DAY_MS
3854 return Date . UTC ( d . getUTCFullYear ( ) , d . getUTCMonth ( ) , d . getUTCDate ( ) + 1 )
3955}
4056
@@ -93,8 +109,7 @@ export function extrapolateLastValue(params: {
93109 const { series, granularity, lastDateMs, referenceMs, predictionPoints } = params
94110 const last = series . at ( - 1 ) ?? 0
95111
96- // Weekly dates are stored as timestampEnd; bucket start is 6 days earlier
97- const bucketTs = granularity === 'weekly' ? lastDateMs - 6 * 86_400_000 : lastDateMs
112+ const bucketTs = lastDateMs
98113 const ratio = getCompletionRatio ( bucketTs , granularity , referenceMs )
99114
100115 if ( ! ( ratio > 0 && ratio < 1 ) || predictionPoints <= 0 ) return last
0 commit comments