@@ -13,6 +13,7 @@ import {
1313 resolveReportingTimeZone ,
1414 startOfZonedDay ,
1515 startOfZonedInterval ,
16+ timeZoneOffsetMinutes ,
1617} from "@/lib/dashboard/time-zone" ;
1718
1819import { requireActor } from "./admin-auth" ;
@@ -288,7 +289,11 @@ function buildCountByBucketSql(input: {
288289 const dataset = analyticsDatasetIdentifier ( input . dataset ) ;
289290 const fromSeconds = Math . floor ( input . from / 1000 ) ;
290291 const toSeconds = Math . ceil ( input . to / 1000 ) ;
291- const bucketExpression = `toUnixTimestamp(toStartOfInterval(timestamp, INTERVAL 1 ${ analyticsBucketUnit ( input . interval ) } , ${ analyticsSqlString ( input . timeZone ) } )) * 1000` ;
292+ const bucketSeconds = Math . max ( 60 , Math . floor ( input . bucketMs / 1000 ) ) ;
293+ const bucketOffsetSeconds =
294+ timeZoneOffsetMinutes ( input . timeZone , input . from ) * 60 +
295+ ( input . interval === "week" ? 3 * 24 * 60 * 60 : 0 ) ;
296+ const bucketExpression = `(intDiv(toUnixTimestamp(timestamp) + ${ bucketOffsetSeconds } , ${ bucketSeconds } ) * ${ bucketSeconds } - ${ bucketOffsetSeconds } ) * 1000` ;
292297 const latencySelect =
293298 input . includeLatency && input . source === "normal"
294299 ? `,
@@ -309,13 +314,6 @@ function buildCountByBucketSql(input: {
309314 ` ;
310315}
311316
312- function analyticsBucketUnit ( interval : BotAnalyticsInterval ) : string {
313- if ( interval === "minute" ) return "MINUTE" ;
314- if ( interval === "hour" ) return "HOUR" ;
315- if ( interval === "week" ) return "WEEK" ;
316- return "DAY" ;
317- }
318-
319317function buildMapPointsSql ( input : {
320318 dataset : string ;
321319 from : number ;
@@ -949,7 +947,11 @@ function mergeTrendRows(input: {
949947 } ) ;
950948 }
951949 for ( const row of input . abnormalRows ) {
952- const timestampMs = Math . floor ( toFiniteNumber ( row . timestampMs ) ) ;
950+ const timestampMs = bucketTimestamp (
951+ Math . floor ( toFiniteNumber ( row . timestampMs ) ) ,
952+ input . interval ,
953+ input . timeZone ,
954+ ) ;
953955 const current = trend . get ( timestampMs ) ;
954956 if ( ! current ) continue ;
955957 current . abnormalCount = Math . max ( 0 , Math . trunc ( toFiniteNumber ( row . count ) ) ) ;
@@ -961,7 +963,11 @@ function mergeTrendRows(input: {
961963 ) ;
962964 }
963965 for ( const row of input . normalRows ) {
964- const timestampMs = Math . floor ( toFiniteNumber ( row . timestampMs ) ) ;
966+ const timestampMs = bucketTimestamp (
967+ Math . floor ( toFiniteNumber ( row . timestampMs ) ) ,
968+ input . interval ,
969+ input . timeZone ,
970+ ) ;
965971 const current = trend . get ( timestampMs ) ;
966972 if ( ! current ) continue ;
967973 current . normalCount = Math . max ( 0 , Math . trunc ( toFiniteNumber ( row . count ) ) ) ;
0 commit comments