123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- import moment from 'moment';
- import {parseStatsPeriod} from 'sentry/components/organizations/pageFilters/parse';
- import ConfigStore from 'sentry/stores/configStore';
- import {DateString} from 'sentry/types';
- // TODO(billy): Move to TimeRangeSelector specific utils
- export const DEFAULT_DAY_START_TIME = '00:00:00';
- export const DEFAULT_DAY_END_TIME = '23:59:59';
- const DATE_FORMAT_NO_TIMEZONE = 'YYYY/MM/DD HH:mm:ss';
- function getParser(local: boolean = false): typeof moment | typeof moment.utc {
- return local ? moment : moment.utc;
- }
- /**
- * Checks if string is valid time. Only accepts 24 hour format.
- *
- * Chrome's time input will (at least for US locale), allow you to input 12
- * hour format with AM/PM but the raw value is in 24 hour.
- *
- * Safari does not do any validation so you could get a value of > 24 hours
- */
- export function isValidTime(str: string): boolean {
- return moment(str, 'HH:mm', true).isValid();
- }
- /**
- * Given a date object, format in datetime in UTC
- * given: Tue Oct 09 2018 00:00:00 GMT-0700 (Pacific Daylight Time)
- * returns: "2018-10-09T07:00:00.000"
- */
- export function getUtcDateString(dateObj: moment.MomentInput): string {
- return moment.utc(dateObj).format(moment.HTML5_FMT.DATETIME_LOCAL_SECONDS);
- }
- export function getFormattedDate(
- dateObj: moment.MomentInput,
- format: string,
- {local}: {local?: boolean} = {}
- ): string {
- return getParser(local)(dateObj).format(format);
- }
- /**
- * Returns user timezone from their account preferences
- */
- export function getUserTimezone(): string {
- return ConfigStore.get('user')?.options?.timezone;
- }
- /**
- * Given a UTC date, return a Date object in local time
- */
- export function getUtcToLocalDateObject(date: moment.MomentInput): Date {
- return moment.utc(date).local().toDate();
- }
- /**
- * Sets time (hours + minutes) of the current date object
- *
- * @param {String} timeStr Time in 24hr format (HH:mm)
- */
- export function setDateToTime(
- dateObj: string | Date,
- timeStr: string,
- {local}: {local?: boolean} = {}
- ): Date {
- const [hours, minutes, seconds] = timeStr.split(':').map(t => parseInt(t, 10));
- const date = new Date(+dateObj);
- if (local) {
- date.setHours(hours, minutes);
- } else {
- date.setUTCHours(hours, minutes);
- }
- if (typeof seconds !== 'undefined') {
- date.setSeconds(seconds);
- }
- return date;
- }
- /**
- * Given a UTC timestamp, return a system date object with the same date
- * e.g. given: system is -0700 (PST),
- * 1/1/2001 @ 22:00 UTC, return: 1/1/2001 @ 22:00 -0700 (PST)
- */
- export function getUtcToSystem(dateObj: moment.MomentInput): Date {
- // This is required because if your system timezone !== user configured timezone
- // then there will be a mismatch of dates with `react-date-picker`
- //
- // We purposely strip the timezone when formatting from the utc timezone
- return new Date(moment.utc(dateObj).format(DATE_FORMAT_NO_TIMEZONE));
- }
- /**
- * Given a timestamp, format to user preference timezone, and strip timezone to
- * return a system date object with the same date
- *
- * e.g. given: system is -0700 (PST) and user preference is -0400 (EST),
- * 1/1/2001 @ 22:00 UTC --> 1/1/2001 @ 18:00 -0400 (EST) -->
- * return: 1/1/2001 @ 18:00 -0700 (PST)
- */
- export function getLocalToSystem(dateObj: moment.MomentInput): Date {
- // This is required because if your system timezone !== user configured timezone
- // then there will be a mismatch of dates with `react-date-picker`
- //
- // We purposely strip the timezone when formatting from the utc timezone
- return new Date(moment(dateObj).format(DATE_FORMAT_NO_TIMEZONE));
- }
- // Get the beginning of day (e.g. midnight)
- export function getStartOfDay(date: moment.MomentInput): Date {
- return moment(date)
- .startOf('day')
- .startOf('hour')
- .startOf('minute')
- .startOf('second')
- .local()
- .toDate();
- }
- // Get tomorrow at midnight so that default endtime
- // is inclusive of today
- export function getEndOfDay(date: moment.MomentInput): Date {
- return moment(date)
- .add(1, 'day')
- .startOf('hour')
- .startOf('minute')
- .startOf('second')
- .subtract(1, 'second')
- .local()
- .toDate();
- }
- export function getPeriodAgo(
- period: moment.unitOfTime.DurationConstructor,
- unit: number
- ): moment.Moment {
- return moment().local().subtract(unit, period);
- }
- // Get the start of the day (midnight) for a period ago
- //
- // e.g. 2 weeks ago at midnight
- export function getStartOfPeriodAgo(
- period: moment.unitOfTime.DurationConstructor,
- unit: number
- ): Date {
- return getStartOfDay(getPeriodAgo(period, unit));
- }
- /**
- * Convert an interval string into a number of seconds.
- * This allows us to create end timestamps from starting ones
- * enabling us to find events in narrow windows.
- *
- * @param {String} interval The interval to convert.
- * @return {Integer}
- */
- export function intervalToMilliseconds(interval: string): number {
- const pattern = /^(\d+)(d|h|m)$/;
- const matches = pattern.exec(interval);
- if (!matches) {
- return 0;
- }
- const [, value, unit] = matches;
- const multipliers = {
- d: 60 * 60 * 24,
- h: 60 * 60,
- m: 60,
- };
- return parseInt(value, 10) * multipliers[unit] * 1000;
- }
- /**
- * This parses our period shorthand strings (e.g. <int><unit>)
- * and converts it into hours
- */
- export function parsePeriodToHours(str: string): number {
- const result = parseStatsPeriod(str);
- if (!result) {
- return -1;
- }
- const {period, periodLength} = result;
- const periodNumber = parseInt(period, 10);
- switch (periodLength) {
- case 's':
- return periodNumber / (60 * 60);
- case 'm':
- return periodNumber / 60;
- case 'h':
- return periodNumber;
- case 'd':
- return periodNumber * 24;
- case 'w':
- return periodNumber * 24 * 7;
- default:
- return -1;
- }
- }
- export function statsPeriodToDays(
- statsPeriod?: string | null,
- start?: DateString,
- end?: DateString
- ) {
- if (statsPeriod && statsPeriod.endsWith('d')) {
- return parseInt(statsPeriod.slice(0, -1), 10);
- }
- if (statsPeriod && statsPeriod.endsWith('h')) {
- return parseInt(statsPeriod.slice(0, -1), 10) / 24;
- }
- if (start && end) {
- return (new Date(end).getTime() - new Date(start).getTime()) / (24 * 60 * 60 * 1000);
- }
- return 0;
- }
- export function shouldUse24Hours() {
- return ConfigStore.get('user')?.options?.clock24Hours;
- }
- export function getTimeFormat({displaySeconds = false}: {displaySeconds?: boolean} = {}) {
- if (shouldUse24Hours()) {
- return displaySeconds ? 'HH:mm:ss' : 'HH:mm';
- }
- return displaySeconds ? 'LTS' : 'LT';
- }
- export function getInternalDate(date: string | Date, utc?: boolean | null) {
- if (utc) {
- return getUtcToSystem(date);
- }
- return new Date(
- moment.tz(moment.utc(date), getUserTimezone()).format('YYYY/MM/DD HH:mm:ss')
- );
- }
- /**
- * Strips timezone from local date, creates a new moment date object with timezone
- * returns the moment as a Date object
- */
- export function getDateWithTimezoneInUtc(date?: Date, utc?: boolean | null) {
- return moment
- .tz(
- moment(date).local().format('YYYY-MM-DD HH:mm:ss'),
- utc ? 'UTC' : getUserTimezone()
- )
- .utc()
- .toDate();
- }
|