blob: 8a4ceaa4c518239ed264632a2e3ec6f8e78100be [file] [log] [blame]
import { TimeGranularity } from '../types';
import createTime from './createTime';
const MS_IN_SECOND = 1000;
const MS_IN_MINUTE = 60 * MS_IN_SECOND;
const MS_IN_HOUR = 60 * MS_IN_MINUTE;
function deductOneMs(time: Date) {
return new Date(time.getTime() - 1);
}
function computeEndTimeFromGranularity(
time: Date,
granularity: TimeGranularity,
useLocalTime: boolean,
) {
const date = useLocalTime ? time.getDate() : time.getUTCDate();
const month = useLocalTime ? time.getMonth() : time.getUTCMonth();
const year = useLocalTime ? time.getFullYear() : time.getUTCFullYear();
const mode = useLocalTime ? 'local' : 'utc';
switch (granularity) {
case TimeGranularity.SECOND:
return new Date(time.getTime() + MS_IN_SECOND - 1);
case TimeGranularity.MINUTE:
return new Date(time.getTime() + MS_IN_MINUTE - 1);
case TimeGranularity.FIVE_MINUTES:
return new Date(time.getTime() + MS_IN_MINUTE * 5 - 1);
case TimeGranularity.TEN_MINUTES:
return new Date(time.getTime() + MS_IN_MINUTE * 10 - 1);
case TimeGranularity.FIFTEEN_MINUTES:
return new Date(time.getTime() + MS_IN_MINUTE * 15 - 1);
case TimeGranularity.HALF_HOUR:
return new Date(time.getTime() + MS_IN_MINUTE * 30 - 1);
case TimeGranularity.HOUR:
return new Date(time.getTime() + MS_IN_HOUR - 1);
// For the day granularity and above, using Date overflow is better than adding timestamp
// because it will also handle daylight saving.
case TimeGranularity.WEEK:
case TimeGranularity.WEEK_STARTING_SUNDAY:
case TimeGranularity.WEEK_STARTING_MONDAY:
return deductOneMs(createTime(mode, year, month, date + 7));
case TimeGranularity.MONTH:
return deductOneMs(createTime(mode, year, month + 1));
case TimeGranularity.QUARTER:
return deductOneMs(createTime(mode, year, (Math.floor(month / 3) + 1) * 3));
case TimeGranularity.YEAR:
return deductOneMs(createTime(mode, year + 1));
// For the WEEK_ENDING_XXX cases,
// currently assume "time" returned from database is supposed to be the end time
// (in contrast to all other granularities that the returned time is start time).
// However, the returned "time" is at 00:00:00.000, so have to add 23:59:59.999.
case TimeGranularity.WEEK_ENDING_SATURDAY:
case TimeGranularity.WEEK_ENDING_SUNDAY:
case TimeGranularity.DATE:
case TimeGranularity.DAY:
default:
return deductOneMs(createTime(mode, year, month, date + 1));
}
}
export default function createTimeRangeFromGranularity(
time: Date,
granularity: TimeGranularity,
useLocalTime = false,
) {
const endTime = computeEndTimeFromGranularity(time, granularity, useLocalTime);
if (
granularity === TimeGranularity.WEEK_ENDING_SATURDAY ||
granularity === TimeGranularity.WEEK_ENDING_SUNDAY
) {
const date = useLocalTime ? time.getDate() : time.getUTCDate();
const month = useLocalTime ? time.getMonth() : time.getUTCMonth();
const year = useLocalTime ? time.getFullYear() : time.getUTCFullYear();
const startTime = createTime(useLocalTime ? 'local' : 'utc', year, month, date - 6);
return [startTime, endTime];
}
return [time, endTime];
}