mirror of
https://github.com/iib0011/omni-tools.git
synced 2025-09-19 22:19:36 +02:00
7
package-lock.json
generated
7
package-lock.json
generated
@@ -24,6 +24,7 @@
|
|||||||
"@types/omggif": "^1.0.5",
|
"@types/omggif": "^1.0.5",
|
||||||
"browser-image-compression": "^2.0.2",
|
"browser-image-compression": "^2.0.2",
|
||||||
"color": "^4.2.3",
|
"color": "^4.2.3",
|
||||||
|
"dayjs": "^1.11.13",
|
||||||
"formik": "^2.4.6",
|
"formik": "^2.4.6",
|
||||||
"jimp": "^0.22.12",
|
"jimp": "^0.22.12",
|
||||||
"lint-staged": "^15.4.3",
|
"lint-staged": "^15.4.3",
|
||||||
@@ -4674,6 +4675,12 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/dayjs": {
|
||||||
|
"version": "1.11.13",
|
||||||
|
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz",
|
||||||
|
"integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/debug": {
|
"node_modules/debug": {
|
||||||
"version": "4.3.5",
|
"version": "4.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
|
||||||
|
@@ -41,6 +41,7 @@
|
|||||||
"@types/omggif": "^1.0.5",
|
"@types/omggif": "^1.0.5",
|
||||||
"browser-image-compression": "^2.0.2",
|
"browser-image-compression": "^2.0.2",
|
||||||
"color": "^4.2.3",
|
"color": "^4.2.3",
|
||||||
|
"dayjs": "^1.11.13",
|
||||||
"formik": "^2.4.6",
|
"formik": "^2.4.6",
|
||||||
"jimp": "^0.22.12",
|
"jimp": "^0.22.12",
|
||||||
"lint-staged": "^15.4.3",
|
"lint-staged": "^15.4.3",
|
||||||
|
@@ -1,3 +1,12 @@
|
|||||||
|
import dayjs from 'dayjs';
|
||||||
|
import utc from 'dayjs/plugin/utc';
|
||||||
|
import timezone from 'dayjs/plugin/timezone';
|
||||||
|
import duration from 'dayjs/plugin/duration';
|
||||||
|
|
||||||
|
dayjs.extend(utc);
|
||||||
|
dayjs.extend(timezone);
|
||||||
|
dayjs.extend(duration);
|
||||||
|
|
||||||
export const unitHierarchy = [
|
export const unitHierarchy = [
|
||||||
'years',
|
'years',
|
||||||
'months',
|
'months',
|
||||||
@@ -11,70 +20,153 @@ export const unitHierarchy = [
|
|||||||
export type TimeUnit = (typeof unitHierarchy)[number];
|
export type TimeUnit = (typeof unitHierarchy)[number];
|
||||||
export type TimeDifference = Record<TimeUnit, number>;
|
export type TimeDifference = Record<TimeUnit, number>;
|
||||||
|
|
||||||
|
// Mapping common abbreviations to IANA time zone names
|
||||||
|
export const tzMap: { [abbr: string]: string } = {
|
||||||
|
EST: 'America/New_York',
|
||||||
|
EDT: 'America/New_York',
|
||||||
|
CST: 'America/Chicago',
|
||||||
|
CDT: 'America/Chicago',
|
||||||
|
MST: 'America/Denver',
|
||||||
|
MDT: 'America/Denver',
|
||||||
|
PST: 'America/Los_Angeles',
|
||||||
|
PDT: 'America/Los_Angeles',
|
||||||
|
GMT: 'Etc/GMT',
|
||||||
|
UTC: 'Etc/UTC'
|
||||||
|
// add more mappings as needed
|
||||||
|
};
|
||||||
|
|
||||||
|
// Parse a date string with a time zone abbreviation,
|
||||||
|
// e.g. "02/02/2024 14:55 EST"
|
||||||
|
export const parseWithTZ = (dateTimeStr: string): dayjs.Dayjs => {
|
||||||
|
const parts = dateTimeStr.trim().split(' ');
|
||||||
|
const tzAbbr = parts.pop()!; // extract the timezone part (e.g., EST)
|
||||||
|
const dateTimePart = parts.join(' ');
|
||||||
|
const tzName = tzMap[tzAbbr];
|
||||||
|
if (!tzName) {
|
||||||
|
throw new Error(`Timezone abbreviation ${tzAbbr} not supported`);
|
||||||
|
}
|
||||||
|
// Parse using the format "MM/DD/YYYY HH:mm" in the given time zone
|
||||||
|
return dayjs.tz(dateTimePart, 'MM/DD/YYYY HH:mm', tzName);
|
||||||
|
};
|
||||||
|
|
||||||
export const calculateTimeBetweenDates = (
|
export const calculateTimeBetweenDates = (
|
||||||
startDate: Date,
|
startDate: Date,
|
||||||
endDate: Date
|
endDate: Date
|
||||||
): TimeDifference => {
|
): TimeDifference => {
|
||||||
if (endDate < startDate) {
|
let start = dayjs(startDate);
|
||||||
const temp = startDate;
|
let end = dayjs(endDate);
|
||||||
startDate = endDate;
|
|
||||||
endDate = temp;
|
// Swap dates if start is after end
|
||||||
|
if (end.isBefore(start)) {
|
||||||
|
[start, end] = [end, start];
|
||||||
}
|
}
|
||||||
|
|
||||||
const milliseconds = endDate.getTime() - startDate.getTime();
|
// Calculate each unit incrementally so that the remainder is applied for subsequent units.
|
||||||
const seconds = Math.floor(milliseconds / 1000);
|
const years = end.diff(start, 'year');
|
||||||
const minutes = Math.floor(seconds / 60);
|
const startPlusYears = start.add(years, 'year');
|
||||||
const hours = Math.floor(minutes / 60);
|
|
||||||
const days = Math.floor(hours / 24);
|
|
||||||
|
|
||||||
// Approximate months and years
|
const months = end.diff(startPlusYears, 'month');
|
||||||
const startYear = startDate.getFullYear();
|
const startPlusMonths = startPlusYears.add(months, 'month');
|
||||||
const startMonth = startDate.getMonth();
|
|
||||||
const endYear = endDate.getFullYear();
|
|
||||||
const endMonth = endDate.getMonth();
|
|
||||||
|
|
||||||
const months = (endYear - startYear) * 12 + (endMonth - startMonth);
|
const days = end.diff(startPlusMonths, 'day');
|
||||||
const years = Math.floor(months / 12);
|
const startPlusDays = startPlusMonths.add(days, 'day');
|
||||||
|
|
||||||
|
const hours = end.diff(startPlusDays, 'hour');
|
||||||
|
const startPlusHours = startPlusDays.add(hours, 'hour');
|
||||||
|
|
||||||
|
const minutes = end.diff(startPlusHours, 'minute');
|
||||||
|
const startPlusMinutes = startPlusHours.add(minutes, 'minute');
|
||||||
|
|
||||||
|
const seconds = end.diff(startPlusMinutes, 'second');
|
||||||
|
const startPlusSeconds = startPlusMinutes.add(seconds, 'second');
|
||||||
|
|
||||||
|
const milliseconds = end.diff(startPlusSeconds, 'millisecond');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
milliseconds,
|
years,
|
||||||
seconds,
|
|
||||||
minutes,
|
|
||||||
hours,
|
|
||||||
days,
|
|
||||||
months,
|
months,
|
||||||
years
|
days,
|
||||||
|
hours,
|
||||||
|
minutes,
|
||||||
|
seconds,
|
||||||
|
milliseconds
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Calculate duration between two date strings with timezone abbreviations
|
||||||
|
export const getDuration = (
|
||||||
|
startStr: string,
|
||||||
|
endStr: string
|
||||||
|
): TimeDifference => {
|
||||||
|
const start = parseWithTZ(startStr);
|
||||||
|
const end = parseWithTZ(endStr);
|
||||||
|
|
||||||
|
if (end.isBefore(start)) {
|
||||||
|
throw new Error('End date must be after start date');
|
||||||
|
}
|
||||||
|
|
||||||
|
return calculateTimeBetweenDates(start.toDate(), end.toDate());
|
||||||
|
};
|
||||||
|
|
||||||
export const formatTimeDifference = (
|
export const formatTimeDifference = (
|
||||||
difference: TimeDifference,
|
difference: TimeDifference,
|
||||||
includeUnits: TimeUnit[] = unitHierarchy.slice(0, -1)
|
includeUnits: TimeUnit[] = unitHierarchy.slice(0, -2)
|
||||||
): string => {
|
): string => {
|
||||||
const timeUnits: { key: TimeUnit; value: number; divisor?: number }[] = [
|
// First normalize the values (convert 24 hours to 1 day, etc.)
|
||||||
{ key: 'years', value: difference.years },
|
const normalized = { ...difference };
|
||||||
{ key: 'months', value: difference.months, divisor: 12 },
|
|
||||||
{ key: 'days', value: difference.days, divisor: 30 },
|
// Convert milliseconds to seconds
|
||||||
{ key: 'hours', value: difference.hours, divisor: 24 },
|
if (normalized.milliseconds >= 1000) {
|
||||||
{ key: 'minutes', value: difference.minutes, divisor: 60 },
|
const additionalSeconds = Math.floor(normalized.milliseconds / 1000);
|
||||||
{ key: 'seconds', value: difference.seconds, divisor: 60 }
|
normalized.seconds += additionalSeconds;
|
||||||
|
normalized.milliseconds %= 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert seconds to minutes
|
||||||
|
if (normalized.seconds >= 60) {
|
||||||
|
const additionalMinutes = Math.floor(normalized.seconds / 60);
|
||||||
|
normalized.minutes += additionalMinutes;
|
||||||
|
normalized.seconds %= 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert minutes to hours
|
||||||
|
if (normalized.minutes >= 60) {
|
||||||
|
const additionalHours = Math.floor(normalized.minutes / 60);
|
||||||
|
normalized.hours += additionalHours;
|
||||||
|
normalized.minutes %= 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert hours to days if 24 or more
|
||||||
|
if (normalized.hours >= 24) {
|
||||||
|
const additionalDays = Math.floor(normalized.hours / 24);
|
||||||
|
normalized.days += additionalDays;
|
||||||
|
normalized.hours %= 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
const timeUnits: { key: TimeUnit; value: number; label: string }[] = [
|
||||||
|
{ key: 'years', value: normalized.years, label: 'year' },
|
||||||
|
{ key: 'months', value: normalized.months, label: 'month' },
|
||||||
|
{ key: 'days', value: normalized.days, label: 'day' },
|
||||||
|
{ key: 'hours', value: normalized.hours, label: 'hour' },
|
||||||
|
{ key: 'minutes', value: normalized.minutes, label: 'minute' },
|
||||||
|
{ key: 'seconds', value: normalized.seconds, label: 'second' },
|
||||||
|
{
|
||||||
|
key: 'milliseconds',
|
||||||
|
value: normalized.milliseconds,
|
||||||
|
label: 'millisecond'
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const parts = timeUnits
|
const parts = timeUnits
|
||||||
.filter(({ key }) => includeUnits.includes(key))
|
.filter(({ key }) => includeUnits.includes(key))
|
||||||
.map(({ key, value, divisor }) => {
|
.map(({ value, label }) => {
|
||||||
const remaining = divisor ? value % divisor : value;
|
if (value === 0) return '';
|
||||||
return remaining > 0 ? `${remaining} ${key}` : '';
|
return `${value} ${label}${value === 1 ? '' : 's'}`;
|
||||||
})
|
})
|
||||||
.filter(Boolean);
|
.filter(Boolean);
|
||||||
|
|
||||||
if (parts.length === 0) {
|
if (parts.length === 0) {
|
||||||
if (includeUnits.includes('milliseconds')) {
|
return '0 minutes';
|
||||||
return `${difference.milliseconds} millisecond${
|
|
||||||
difference.milliseconds === 1 ? '' : 's'
|
|
||||||
}`;
|
|
||||||
}
|
|
||||||
return '0 seconds';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return parts.join(', ');
|
return parts.join(', ');
|
||||||
@@ -85,45 +177,49 @@ export const getTimeWithTimezone = (
|
|||||||
timeString: string,
|
timeString: string,
|
||||||
timezone: string
|
timezone: string
|
||||||
): Date => {
|
): Date => {
|
||||||
// Combine date and time
|
|
||||||
const dateTimeString = `${dateString}T${timeString}Z`; // Append 'Z' to enforce UTC parsing
|
|
||||||
const utcDate = new Date(dateTimeString);
|
|
||||||
|
|
||||||
if (isNaN(utcDate.getTime())) {
|
|
||||||
throw new Error('Invalid date or time format');
|
|
||||||
}
|
|
||||||
|
|
||||||
// If timezone is "local", return the local date
|
// If timezone is "local", return the local date
|
||||||
if (timezone === 'local') {
|
if (timezone === 'local') {
|
||||||
return utcDate;
|
const dateTimeString = `${dateString}T${timeString}`;
|
||||||
|
return dayjs(dateTimeString).toDate();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract offset from timezone (e.g., "GMT+5:30" or "GMT-4")
|
// Check if the timezone is a known abbreviation
|
||||||
|
if (tzMap[timezone]) {
|
||||||
|
const dateTimeString = `${dateString} ${timeString}`;
|
||||||
|
return dayjs
|
||||||
|
.tz(dateTimeString, 'YYYY-MM-DD HH:mm', tzMap[timezone])
|
||||||
|
.toDate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle GMT+/- format
|
||||||
const match = timezone.match(/^GMT(?:([+-]\d{1,2})(?::(\d{2}))?)?$/);
|
const match = timezone.match(/^GMT(?:([+-]\d{1,2})(?::(\d{2}))?)?$/);
|
||||||
if (!match) {
|
if (!match) {
|
||||||
throw new Error('Invalid timezone format');
|
throw new Error('Invalid timezone format');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const dateTimeString = `${dateString}T${timeString}Z`;
|
||||||
|
const utcDate = dayjs.utc(dateTimeString);
|
||||||
|
|
||||||
|
if (!utcDate.isValid()) {
|
||||||
|
throw new Error('Invalid date or time format');
|
||||||
|
}
|
||||||
|
|
||||||
const offsetHours = match[1] ? parseInt(match[1], 10) : 0;
|
const offsetHours = match[1] ? parseInt(match[1], 10) : 0;
|
||||||
const offsetMinutes = match[2] ? parseInt(match[2], 10) : 0;
|
const offsetMinutes = match[2] ? parseInt(match[2], 10) : 0;
|
||||||
|
|
||||||
const totalOffsetMinutes =
|
const totalOffsetMinutes =
|
||||||
offsetHours * 60 + (offsetHours < 0 ? -offsetMinutes : offsetMinutes);
|
offsetHours * 60 + (offsetHours < 0 ? -offsetMinutes : offsetMinutes);
|
||||||
|
|
||||||
// Adjust the UTC date by the timezone offset
|
return utcDate.subtract(totalOffsetMinutes, 'minute').toDate();
|
||||||
return new Date(utcDate.getTime() - totalOffsetMinutes * 60 * 1000);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Helper function to format time based on largest unit
|
|
||||||
export const formatTimeWithLargestUnit = (
|
export const formatTimeWithLargestUnit = (
|
||||||
difference: TimeDifference,
|
difference: TimeDifference,
|
||||||
largestUnit: TimeUnit
|
largestUnit: TimeUnit
|
||||||
): string => {
|
): string => {
|
||||||
const largestUnitIndex = unitHierarchy.indexOf(largestUnit);
|
const largestUnitIndex = unitHierarchy.indexOf(largestUnit);
|
||||||
const unitsToInclude = unitHierarchy.slice(largestUnitIndex);
|
const unitsToInclude = unitHierarchy.slice(
|
||||||
|
largestUnitIndex,
|
||||||
// Preserve only whole values, do not apply fractional conversions
|
unitHierarchy.length // Include milliseconds if it's the largest unit requested
|
||||||
const adjustedDifference: TimeDifference = { ...difference };
|
);
|
||||||
|
return formatTimeDifference(difference, unitsToInclude);
|
||||||
return formatTimeDifference(adjustedDifference, unitsToInclude);
|
|
||||||
};
|
};
|
||||||
|
@@ -1,4 +1,8 @@
|
|||||||
import { describe, expect, it } from 'vitest';
|
import { describe, expect, it } from 'vitest';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import utc from 'dayjs/plugin/utc';
|
||||||
|
import timezone from 'dayjs/plugin/timezone';
|
||||||
|
import duration from 'dayjs/plugin/duration';
|
||||||
import {
|
import {
|
||||||
calculateTimeBetweenDates,
|
calculateTimeBetweenDates,
|
||||||
formatTimeDifference,
|
formatTimeDifference,
|
||||||
@@ -6,31 +10,78 @@ import {
|
|||||||
getTimeWithTimezone
|
getTimeWithTimezone
|
||||||
} from './service';
|
} from './service';
|
||||||
|
|
||||||
|
dayjs.extend(utc);
|
||||||
|
dayjs.extend(timezone);
|
||||||
|
dayjs.extend(duration);
|
||||||
|
|
||||||
// Utility function to create a date
|
// Utility function to create a date
|
||||||
const createDate = (
|
const createDate = (
|
||||||
year: number,
|
year: number,
|
||||||
month: number,
|
month: number,
|
||||||
day: number,
|
day: number,
|
||||||
hours = 0,
|
hours = 0,
|
||||||
minutes = 0,
|
minutes = 0
|
||||||
seconds = 0
|
) => dayjs.utc(Date.UTC(year, month - 1, day, hours, minutes)).toDate();
|
||||||
) => new Date(Date.UTC(year, month - 1, day, hours, minutes, seconds));
|
|
||||||
describe('calculateTimeBetweenDates', () => {
|
describe('calculateTimeBetweenDates', () => {
|
||||||
it('should calculate the correct time difference', () => {
|
it('should calculate exactly 1 year difference', () => {
|
||||||
const startDate = createDate(2023, 1, 1);
|
const startDate = createDate(2023, 1, 1);
|
||||||
const endDate = createDate(2024, 1, 1);
|
const endDate = createDate(2024, 1, 1);
|
||||||
const result = calculateTimeBetweenDates(startDate, endDate);
|
const result = calculateTimeBetweenDates(startDate, endDate);
|
||||||
|
|
||||||
expect(result.years).toBe(1);
|
expect(result.years).toBe(1);
|
||||||
expect(result.months).toBe(12);
|
expect(result.months).toBe(0);
|
||||||
expect(result.days).toBeGreaterThanOrEqual(365);
|
expect(result.days).toBe(0);
|
||||||
|
expect(result.hours).toBe(0);
|
||||||
|
expect(result.minutes).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should calculate 1 year and 1 day difference', () => {
|
||||||
|
const startDate = createDate(2023, 1, 1);
|
||||||
|
const endDate = createDate(2024, 1, 2);
|
||||||
|
const result = calculateTimeBetweenDates(startDate, endDate);
|
||||||
|
|
||||||
|
expect(result.years).toBe(1);
|
||||||
|
expect(result.months).toBe(0);
|
||||||
|
expect(result.days).toBe(1);
|
||||||
|
expect(result.hours).toBe(0);
|
||||||
|
expect(result.minutes).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle leap year correctly', () => {
|
||||||
|
const startDate = createDate(2024, 2, 28); // February 28th in leap year
|
||||||
|
const endDate = createDate(2024, 3, 1); // March 1st
|
||||||
|
const result = calculateTimeBetweenDates(startDate, endDate);
|
||||||
|
|
||||||
|
expect(result.days).toBe(2);
|
||||||
|
expect(result.months).toBe(0);
|
||||||
|
expect(result.years).toBe(0);
|
||||||
|
expect(result.hours).toBe(0);
|
||||||
|
expect(result.minutes).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should swap dates if startDate is after endDate', () => {
|
it('should swap dates if startDate is after endDate', () => {
|
||||||
const startDate = createDate(2024, 1, 1);
|
const startDate = createDate(2024, 1, 1);
|
||||||
const endDate = createDate(2023, 1, 1);
|
const endDate = createDate(2023, 1, 1);
|
||||||
const result = calculateTimeBetweenDates(startDate, endDate);
|
const result = calculateTimeBetweenDates(startDate, endDate);
|
||||||
|
|
||||||
expect(result.years).toBe(1);
|
expect(result.years).toBe(1);
|
||||||
|
expect(result.months).toBe(0);
|
||||||
|
expect(result.days).toBe(0);
|
||||||
|
expect(result.hours).toBe(0);
|
||||||
|
expect(result.minutes).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle same day different hours', () => {
|
||||||
|
const startDate = createDate(2024, 1, 1, 10);
|
||||||
|
const endDate = createDate(2024, 1, 1, 15);
|
||||||
|
const result = calculateTimeBetweenDates(startDate, endDate);
|
||||||
|
|
||||||
|
expect(result.years).toBe(0);
|
||||||
|
expect(result.months).toBe(0);
|
||||||
|
expect(result.days).toBe(0);
|
||||||
|
expect(result.hours).toBe(5);
|
||||||
|
expect(result.minutes).toBe(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -46,11 +97,26 @@ describe('formatTimeDifference', () => {
|
|||||||
milliseconds: 0
|
milliseconds: 0
|
||||||
};
|
};
|
||||||
expect(formatTimeDifference(difference)).toBe(
|
expect(formatTimeDifference(difference)).toBe(
|
||||||
'1 years, 2 months, 10 days, 5 hours, 30 minutes'
|
'1 year, 2 months, 10 days, 5 hours, 30 minutes'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return 0 seconds if all values are zero', () => {
|
it('should handle singular units correctly', () => {
|
||||||
|
const difference = {
|
||||||
|
years: 1,
|
||||||
|
months: 1,
|
||||||
|
days: 1,
|
||||||
|
hours: 1,
|
||||||
|
minutes: 1,
|
||||||
|
seconds: 0,
|
||||||
|
milliseconds: 0
|
||||||
|
};
|
||||||
|
expect(formatTimeDifference(difference)).toBe(
|
||||||
|
'1 year, 1 month, 1 day, 1 hour, 1 minute'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return 0 minutes if all values are zero', () => {
|
||||||
expect(
|
expect(
|
||||||
formatTimeDifference({
|
formatTimeDifference({
|
||||||
years: 0,
|
years: 0,
|
||||||
@@ -61,7 +127,7 @@ describe('formatTimeDifference', () => {
|
|||||||
seconds: 0,
|
seconds: 0,
|
||||||
milliseconds: 0
|
milliseconds: 0
|
||||||
})
|
})
|
||||||
).toBe('0 seconds');
|
).toBe('0 minutes');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -85,12 +151,12 @@ describe('formatTimeWithLargestUnit', () => {
|
|||||||
months: 1,
|
months: 1,
|
||||||
days: 15,
|
days: 15,
|
||||||
hours: 12,
|
hours: 12,
|
||||||
minutes: 0,
|
minutes: 30,
|
||||||
seconds: 0,
|
seconds: 0,
|
||||||
milliseconds: 0
|
milliseconds: 0
|
||||||
};
|
};
|
||||||
expect(formatTimeWithLargestUnit(difference, 'days')).toContain(
|
expect(formatTimeWithLargestUnit(difference, 'days')).toBe(
|
||||||
'15 days, 12 hours'
|
'15 days, 12 hours, 30 minutes'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Reference in New Issue
Block a user