diff --git a/packages/grafana-ui/src/utils/moment_wrapper.ts b/packages/grafana-ui/src/utils/moment_wrapper.ts index 014a6f06e61..b9e51d1826b 100644 --- a/packages/grafana-ui/src/utils/moment_wrapper.ts +++ b/packages/grafana-ui/src/utils/moment_wrapper.ts @@ -68,6 +68,7 @@ export interface DateTime extends Object { valueOf: () => number; unix: () => number; utc: () => DateTime; + utcOffset: () => number; hour?: () => number; } diff --git a/public/app/plugins/datasource/prometheus/datasource.ts b/public/app/plugins/datasource/prometheus/datasource.ts index 7f62b7e6897..de85be08ebb 100644 --- a/public/app/plugins/datasource/prometheus/datasource.ts +++ b/public/app/plugins/datasource/prometheus/datasource.ts @@ -367,7 +367,7 @@ export class PrometheusDatasource extends DataSourceApi // Align query interval with step to allow query caching and to ensure // that about-same-time query results look the same. - const adjusted = alignRange(start, end, query.step); + const adjusted = alignRange(start, end, query.step, this.timeSrv.timeRange().to.utcOffset() * 60); query.start = adjusted.start; query.end = adjusted.end; this._addTracingHeaders(query, options); @@ -694,10 +694,16 @@ export class PrometheusDatasource extends DataSourceApi * @param start Timestamp marking the beginning of the range. * @param end Timestamp marking the end of the range. * @param step Interval to align start and end with. + * @param utcOffsetSec Number of seconds current timezone is offset from UTC */ -export function alignRange(start: number, end: number, step: number): { end: number; start: number } { - const alignedEnd = Math.floor(end / step) * step; - const alignedStart = Math.floor(start / step) * step; +export function alignRange( + start: number, + end: number, + step: number, + utcOffsetSec: number +): { end: number; start: number } { + const alignedEnd = Math.floor((end + utcOffsetSec) / step) * step - utcOffsetSec; + const alignedStart = Math.floor((start + utcOffsetSec) / step) * step - utcOffsetSec; return { end: alignedEnd, start: alignedStart, diff --git a/public/app/plugins/datasource/prometheus/specs/datasource.test.ts b/public/app/plugins/datasource/prometheus/specs/datasource.test.ts index a70cdf90803..433b6520bdd 100644 --- a/public/app/plugins/datasource/prometheus/specs/datasource.test.ts +++ b/public/app/plugins/datasource/prometheus/specs/datasource.test.ts @@ -219,25 +219,37 @@ describe('PrometheusDatasource', () => { describe('alignRange', () => { it('does not modify already aligned intervals with perfect step', () => { - const range = alignRange(0, 3, 3); + const range = alignRange(0, 3, 3, 0); expect(range.start).toEqual(0); expect(range.end).toEqual(3); }); it('does modify end-aligned intervals to reflect number of steps possible', () => { - const range = alignRange(1, 6, 3); + const range = alignRange(1, 6, 3, 0); expect(range.start).toEqual(0); expect(range.end).toEqual(6); }); it('does align intervals that are a multiple of steps', () => { - const range = alignRange(1, 4, 3); + const range = alignRange(1, 4, 3, 0); expect(range.start).toEqual(0); expect(range.end).toEqual(3); }); it('does align intervals that are not a multiple of steps', () => { - const range = alignRange(1, 5, 3); + const range = alignRange(1, 5, 3, 0); expect(range.start).toEqual(0); expect(range.end).toEqual(3); }); + it('does align intervals with local midnight -UTC offset', () => { + //week range, location 4+ hours UTC offset, 24h step time + const range = alignRange(4 * 60 * 60, (7 * 24 + 4) * 60 * 60, 24 * 60 * 60, -4 * 60 * 60); //04:00 UTC, 7 day range + expect(range.start).toEqual(4 * 60 * 60); + expect(range.end).toEqual((7 * 24 + 4) * 60 * 60); + }); + it('does align intervals with local midnight +UTC offset', () => { + //week range, location 4- hours UTC offset, 24h step time + const range = alignRange(20 * 60 * 60, (8 * 24 - 4) * 60 * 60, 24 * 60 * 60, 4 * 60 * 60); //20:00 UTC on day1, 7 days later is 20:00 on day8 + expect(range.start).toEqual(20 * 60 * 60); + expect(range.end).toEqual((8 * 24 - 4) * 60 * 60); + }); }); describe('extractRuleMappingFromGroups()', () => { @@ -419,7 +431,10 @@ const templateSrv = ({ const timeSrv = ({ timeRange: () => { - return { to: { diff: () => 2000 }, from: '' }; + return { + from: dateTime(1531468681), + to: dateTime(1531468681 + 2000), + }; }, } as unknown) as TimeSrv;