| 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]; |
| } |