Merge branch 'feat/inda-383-daily-stat' into 'main'
[ProtonMail-WebClient.git] / packages / shared / lib / helpers / time.ts
blobe2935bf42d7091666f44bd31776a006d1e46a82c
1 import { format as formatDate, fromUnixTime, getUnixTime, isSameDay } from 'date-fns';
3 import { serverTime } from '@proton/crypto';
5 export type DateFnsOptions = Parameters<typeof formatDate>[2];
7 export type Options = DateFnsOptions & {
8     /**
9      * Date format if `unixTime` argument is today. If false then force `format`. 'p' by default.
10      */
11     sameDayFormat?: string | false;
12     /**
13      * Date format in general case. 'PP' by default.
14      */
15     format?: string;
18 /**
19  * Convert UNIX timestamp into a readable time. The format of the readable time is:
20  * ** Hours and minutes if the UNIX timestamp is from the same day,
21  * ** Day, month and year otherwise
22  */
23 export const readableTime = (unixTime: number, options: Options = {}) => {
24     let { sameDayFormat, format, ...dateFnsOptions } = options;
25     sameDayFormat = sameDayFormat ?? 'p';
26     format = format ?? 'PP';
28     const date = fromUnixTime(unixTime);
30     if (sameDayFormat && isSameDay(date, Date.now())) {
31         return formatDate(date, sameDayFormat, dateFnsOptions);
32     }
34     return formatDate(date, format, dateFnsOptions);
37 export type OptionsWithIntl = {
38     /**
39      * Locale code string, or an array of such strings like 'en' or 'en-US'.
40      */
41     localeCode?: string | string[];
42     /**
43      * If true time will be shown in 12h format with AM/PM
44      */
45     hour12?: boolean;
46     /**
47      * Intl format options.
48      */
49     intlOptions?: Intl.DateTimeFormatOptions;
50     /**
51      * Intl options if readableTimeIntl `unixTime` argument is today.
52      */
53     sameDayIntlOptions?: Intl.DateTimeFormatOptions | false;
56 /**
57  * Convert UNIX timestamp into a readable time with Intl.DateTimeFormat API. The format of the readable time is:
58  * ** Hours and minutes if the UNIX timestamp is from the same day,
59  * ** Day, month and year otherwise
60  * @param unixTime {number}
61  * @param {Object} options
62  * @param {Object} [options.intlOptions={month: 'short', day: 'numeric', year: 'numeric'}]
63  * @param {Object} [options.sameDayIntlOptions={month: 'short', day: 'numeric', year: 'numeric'}]
64  */
65 export const readableTimeIntl = (unixTime: number, options: OptionsWithIntl = {}) => {
66     let { sameDayIntlOptions, localeCode = 'en-US', hour12, intlOptions } = options;
67     // h12: 12:59 AM | h23: 00:59 (h24 would have produced: 24:59)
68     // We still want to let default Intl behavior if no hour12 params is pass, so we want to have undefined
69     const hourCycle = (hour12 === true && 'h12') || (hour12 === false && 'h23') || undefined;
71     const defaultIntlOptions: Intl.DateTimeFormatOptions = { month: 'short', day: 'numeric', year: 'numeric' };
72     intlOptions = intlOptions ?? defaultIntlOptions;
74     const defaultSameDayOptions: Intl.DateTimeFormatOptions = { hour: 'numeric', minute: 'numeric' };
75     sameDayIntlOptions = sameDayIntlOptions ?? defaultSameDayOptions;
77     const date = new Date(unixTime * 1000);
79     if (sameDayIntlOptions && isSameDay(date, Date.now())) {
80         return Intl.DateTimeFormat(localeCode, { hourCycle, ...sameDayIntlOptions }).format(date);
81     }
82     return Intl.DateTimeFormat(localeCode, { hourCycle, ...intlOptions }).format(date);
85 export const getCurrentUnixTimestamp = () => {
86     return getUnixTime(serverTime());