Skip to content

Commit

Permalink
pkp/pkp-lib#10674 Improved edge case date scenarios to accurately cal…
Browse files Browse the repository at this point in the history
…culate days
  • Loading branch information
jardakotesovec committed Feb 20, 2025
1 parent 0c51370 commit f517b8b
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 28 deletions.
45 changes: 21 additions & 24 deletions src/composables/useDate.js
Original file line number Diff line number Diff line change
@@ -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) {
Expand All @@ -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};
}
34 changes: 34 additions & 0 deletions src/composables/useDate.test.js
Original file line number Diff line number Diff line change
@@ -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);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -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());
});
</script>
7 changes: 5 additions & 2 deletions src/pages/dashboard/composables/useReviewActivityLogic.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit f517b8b

Please sign in to comment.