openreplay/frontend/app/date.ts
Andrey Babushkin fd5c0c9747
Add lokalisation (#3092)
* applied eslint

* add locales and lint the project

* removed error boundary

* updated locales

* fix min files

* fix locales
2025-03-06 17:43:15 +01:00

258 lines
7.4 KiB
TypeScript

// @flow
import { DateTime, Duration } from 'luxon'; // TODO
import { Timezone } from 'App/mstore/types/sessionSettings';
import { LAST_24_HOURS, LAST_30_DAYS, LAST_7_DAYS } from 'Types/app/period';
import { CUSTOM_RANGE } from '@/dateRange';
export function getDateFromString(
date: string,
format = 'yyyy-MM-dd HH:mm:ss:SSS',
): string {
return DateTime.fromISO(date).toFormat(format);
}
/**
* Formats a given duration.
*
* @param {Duration | number} inputDuration - The duration to format. Can be a Duration object or a number representing
* milliseconds.
* @returns {string} - Formatted duration string.
*
* @example
*
* // Format a duration from a Duration object
* const duration1 = Duration.fromObject({ hours: 2, minutes: 30 });
* console.log(durationFormatted(duration1)); // Outputs: "2h30m"
*
* // Format a duration from milliseconds
* console.log(durationFormatted(55000)); // Outputs: "55s"
*/
export const durationFormatted = (inputDuration: Duration | number): string => {
let duration: Duration;
if (inputDuration instanceof Duration) {
duration = inputDuration;
} else {
duration = Duration.fromMillis(inputDuration);
}
if (duration.as('minutes') < 1) {
// show in seconds
return duration.toFormat("s's'");
}
if (duration.as('hours') < 1) {
// show in minutes
return duration.toFormat("m'm's's'");
}
if (duration.as('days') < 1) {
// show in hours and minutes
return duration.toFormat("h'h'm'm'");
}
if (duration.as('months') < 1) {
// show in days and hours
return duration.toFormat("d'd'h'h'");
}
return duration.toFormat("m'm's's'");
};
export function durationFromMsFormatted(ms: number): string {
return durationFormatted(Duration.fromMillis(ms || 0));
}
export function shortDurationFromMs(ms: number): string {
const dur = Duration.fromMillis(ms);
return dur.toFormat('mm:ss');
}
export function durationFromMs(ms: number, isFull?: boolean): string {
const dur = Duration.fromMillis(ms);
return dur.toFormat(`hh:mm:ss${isFull ? '.SSS' : ''}`);
}
export const durationFormattedFull = (duration: Duration): string => {
if (duration.as('minutes') < 1) {
// show in seconds
const d = duration.toFormat('s');
duration = d + (d > 1 ? ' seconds' : ' second');
} else if (duration.as('hours') < 1) {
// show in minutes
const d = duration.toFormat('m');
duration = d + (d > 1 ? ' minutes' : ' minute');
} else if (duration.as('days') < 1) {
// show in hours and minutes
const d = duration.toFormat('h');
duration = d + (d > 1 ? ' hours' : ' hour');
} else if (duration.as('months') < 1) {
// show in days and hours
const d = duration.toFormat('d');
duration = d + (d > 1 ? ' days' : ' day');
} else {
const d = Math.trunc(duration.as('months'));
duration = d + (d > 1 ? ' months' : ' month');
}
return duration;
};
export const msToMin = (ms: number): number => Math.round(ms / 60000);
export const msToSec = (ms: number): number => Math.round(ms / 1000);
export const diffFromNowString = (ts: number): string =>
durationFormattedFull(
DateTime.fromMillis(Date.now()).diff(DateTime.fromMillis(ts)),
);
export const diffFromNowShortString = (ts: number): string =>
durationFormatted(
DateTime.fromMillis(Date.now()).diff(DateTime.fromMillis(ts)),
);
export const getDateFromMill = (date) =>
typeof date === 'number' ? DateTime.fromMillis(date) : undefined;
export const getTimeFromMill = (dateTime: number, tz: string) => {
const date = DateTime.fromMillis(dateTime);
return date.setZone(tz).toFormat('HH:mm:ss ZZZZ');
};
/**
* Check if the given date is today.
* @param {Date} Date to be checked.
* @return {Boolean}
*/
export const isToday = (date: DateTime): boolean =>
date.hasSame(new Date(), 'day');
export const isSameYear = (date: DateTime): boolean =>
date.hasSame(new Date(), 'year');
export function formatDateTimeDefault(timestamp: number): string {
const date = DateTime.fromMillis(timestamp);
return isToday(date)
? 'Today'
: `${date.toFormat('LLL dd, yyyy')}, ${date.toFormat('hh:mm a')}`;
}
/**
* Formats timestamps into readable date
* @param {Number} timestamp
* @param {Object} timezone fixed offset like UTC+6
* @returns {String} formatted date (or time if its today)
*/
export function formatTimeOrDate(
timestamp: number,
timezone?: Timezone,
isFull = false,
): string {
let date = DateTime.fromMillis(timestamp);
if (timezone) {
if (timezone.value === 'UTC') date = date.toUTC();
date = date.setZone(timezone.value);
}
if (isFull) {
const strHead = date.toFormat('LLL dd, yyyy, ');
const strTail = date.toFormat('hh:mma').toLowerCase();
return strHead + strTail;
}
if (isToday(date)) {
return date.toFormat('hh:mma').toLowerCase();
}
if (isSameYear(date)) {
const strHead = date.toFormat('LLL dd, ');
const strTail = date.toFormat('hh:mma').toLowerCase();
return strHead + strTail;
}
const strHead = date.toFormat('LLL dd, yyyy, ');
const strTail = date.toFormat('hh:mma').toLowerCase();
return strHead + strTail;
}
/**
* Check if the given date is today/yesterday else return in specified format.
* @param {Date} date Date to be cheked.
* @param {String} format Returning date format.
* @return {String} Formated date string.
*/
export const checkForRecent = (date: DateTime, format: string): string => {
const d = new Date();
// Today
if (date.hasSame(d, 'day')) return 'Today';
// Yesterday
if (date.hasSame(d.setDate(d.getDate() - 1), 'day')) return 'Yesterday';
// Formatted
return date.toFormat(format);
};
export const resentOrDate = (ts, short?: boolean) => {
const date = DateTime.fromMillis(ts);
const d = new Date();
// Today
if (date.hasSame(d, 'day')) return `Today at ${date.toFormat('hh:mm a')}`;
// Yesterday
if (date.hasSame(d.setDate(d.getDate() - 1), 'day'))
return `Yesterday at ${date.toFormat('hh:mm a')}`;
return date.toFormat(`LLL dd, yyyy${short ? '' : ', hh:mm a'}`);
};
export const checkRecentTime = (date, format) => date.toRelative();
export const formatMs = (ms: number): string =>
ms < 1000 ? `${Math.trunc(ms)}ms` : `${Math.trunc(ms / 100) / 10}s`;
export const convertTimestampToUtcTimestamp = (timestamp: number): number =>
DateTime.fromMillis(timestamp).toUTC().toMillis();
export const nowFormatted = (format?: string): string =>
DateTime.local().toFormat(format || 'LLL dd, yyyy, hh:mm a');
export const countDaysFrom = (timestamp: number): number => {
const date = DateTime.fromMillis(timestamp);
const d = new Date();
return Math.round(
Math.abs(d.getTime() - date.toJSDate().getTime()) / (1000 * 3600 * 24),
);
};
export const getDateRangeUTC = (
rangeName: string,
customStartDate?: number,
customEndDate?: number,
): {
startDate: number;
endDate: number;
} => {
let endDate = new Date().getTime();
let startDate: number;
switch (rangeName) {
case LAST_7_DAYS:
startDate = endDate - 7 * 24 * 60 * 60 * 1000;
break;
case LAST_30_DAYS:
startDate = endDate - 30 * 24 * 60 * 60 * 1000;
break;
case CUSTOM_RANGE:
if (!customStartDate || !customEndDate) {
throw new Error(
'Start date and end date must be provided for CUSTOM_RANGE.',
);
}
startDate = customStartDate;
endDate = customEndDate;
break;
case LAST_24_HOURS:
default:
startDate = endDate - 24 * 60 * 60 * 1000;
}
return {
startDate,
endDate,
};
};