diff --git a/src/composables/useDate.js b/src/composables/useDate.js index 05089b1a2..be0d8c825 100644 --- a/src/composables/useDate.js +++ b/src/composables/useDate.js @@ -1,31 +1,28 @@ import moment from 'moment'; +function convertUTCStringDateToDate(stringDate) { + return new Date( + stringDate.includes(' ') + ? stringDate.replace(' ', 'T') + 'Z' // "2025-02-07 05:37:07" -> "2025-02-07T05:37:07Z" + : stringDate + 'T00:00:00Z', // "2025-02-07" -> "2025-02-07T00:00:00Z" + ); +} + export function useDate() { - function calculateDaysFromNow(dateString) { - // Step 1: Parse input as UTC - const inputDate = new Date( - dateString.includes(' ') - ? dateString.replace(' ', 'T') + 'Z' // "2025-02-07 05:37:07" -> "2025-02-07T05:37:07Z" - : dateString + 'T00:00:00Z', // "2025-02-07" -> "2025-02-07T00:00:00Z" - ); + function calculateDaysBetweenDates(startDate, endDate) { + const oneDay = 1000 * 60 * 60 * 24; // milliseconds in one day + const start = + startDate instanceof Date + ? startDate + : convertUTCStringDateToDate(startDate); - // Step 2: Get current date as UTC midnight - const now = new Date(); - const nowUTC = new Date( - Date.UTC( - now.getUTCFullYear(), - now.getUTCMonth(), - now.getUTCDate(), - 0, - 0, - 0, - ), - ); + const end = + endDate instanceof Date ? endDate : convertUTCStringDateToDate(endDate); - // Step 3: Calculate difference in whole days - const diffMilliseconds = inputDate - nowUTC; - const millisecondsPerDay = 1000 * 60 * 60 * 24; // 86,400,000 ms - return Math.floor(diffMilliseconds / millisecondsPerDay); + start.setUTCHours(0, 0, 0, 0); + end.setUTCHours(0, 0, 0, 0); + const difference = end - start; // difference in milliseconds + return Math.round(difference / oneDay); } function formatShortDate(dateString) { @@ -36,5 +33,5 @@ export function useDate() { return moment(dateString).format('YYYY-MM-DD hh:mm A'); } - return {calculateDaysFromNow, formatShortDate, formatDateAndTime}; + return {calculateDaysBetweenDates, formatShortDate, formatDateAndTime}; } diff --git a/src/composables/useDate.test.js b/src/composables/useDate.test.js new file mode 100644 index 000000000..312220ee0 --- /dev/null +++ b/src/composables/useDate.test.js @@ -0,0 +1,34 @@ +import {describe, test, expect} from 'vitest'; +import {useDate} from './useDate'; + +describe('calculateDaysFromNow', () => { + const {calculateDaysBetweenDates} = useDate(); + test('today date should result in 0 days', () => { + expect( + calculateDaysBetweenDates('2025-02-20 08:10:27', '2025-02-20 11:00:00'), + ).toBe(0); + + expect( + calculateDaysBetweenDates('2025-02-20 23:10:27', '2025-02-20 11:00:00'), + ).toBe(0); + }); + test('tomorrow should always result in 1 day', () => { + expect( + calculateDaysBetweenDates('2025-02-19 08:10:27', '2025-02-20 11:00:00'), + ).toBe(1); + + expect( + calculateDaysBetweenDates('2025-02-19 23:10:27', '2025-02-20 11:00:00'), + ).toBe(1); + }); + + test('yesterday should always result in -1 day', () => { + expect( + calculateDaysBetweenDates('2025-02-21 08:10:27', '2025-02-20 11:00:00'), + ).toBe(-1); + + expect( + calculateDaysBetweenDates('2025-02-21 23:10:27', '2025-02-20 11:00:00'), + ).toBe(-1); + }); +}); diff --git a/src/pages/dashboard/components/DashboardTable/CellSubmissionDays.vue b/src/pages/dashboard/components/DashboardTable/CellSubmissionDays.vue index c67ffe771..236092aed 100644 --- a/src/pages/dashboard/components/DashboardTable/CellSubmissionDays.vue +++ b/src/pages/dashboard/components/DashboardTable/CellSubmissionDays.vue @@ -11,9 +11,9 @@ const props = defineProps({ item: {type: Object, required: true}, }); -const {calculateDaysFromNow} = useDate(); +const {calculateDaysBetweenDates} = useDate(); const days = computed(() => { - return calculateDaysFromNow(props.item.dateLastActivity); + return calculateDaysBetweenDates(props.item.dateLastActivity, new Date()); }); diff --git a/src/pages/dashboard/composables/useReviewActivityLogic.js b/src/pages/dashboard/composables/useReviewActivityLogic.js index 2b75a070f..8f1a22a83 100644 --- a/src/pages/dashboard/composables/useReviewActivityLogic.js +++ b/src/pages/dashboard/composables/useReviewActivityLogic.js @@ -4,7 +4,7 @@ import {RecommendationTranslations} from '@/composables/useSubmission'; import {Actions as ReviewerManagerActions} from '@/managers/ReviewerManager/useReviewerManagerActions'; const {tk, t} = useLocalize(); -const {calculateDaysFromNow} = useDate(); +const {calculateDaysBetweenDates} = useDate(); const ReviewActivityActions = { RESEND_REVIEW_REQUEST: 'resendReviewRequest', EDIT_DUE_DATE: 'editDueDate', @@ -270,7 +270,10 @@ const ConfigPerStatus = { function getDays(config, reviewAssignment) { if (config.dateToDisplay) { - return calculateDaysFromNow(reviewAssignment[config.dateToDisplay]); + return calculateDaysBetweenDates( + new Date(), + reviewAssignment[config.dateToDisplay], + ); } return null;