diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 391285d..d32e2e3 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -4,10 +4,9 @@
-
+
+
-
-
@@ -155,6 +154,7 @@
"Vitest.removeDuplicateLines function.newlines option.should filter newlines when newlines is set to filter.executor": "Run",
"Vitest.replaceText function (regexp mode).should return the original text when passed an invalid regexp.executor": "Run",
"Vitest.replaceText function.executor": "Run",
+ "Vitest.timeBetweenDates.executor": "Run",
"git-widget-placeholder": "fork/TheLukasHenry/days-calculator-#51",
"ignore.virus.scanning.warn.message": "true",
"kotlin-language-version-configured": "true",
@@ -206,17 +206,17 @@
-
-
+
+
-
+
+
-
-
+
+
-
-
+
@@ -247,6 +247,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -263,30 +276,20 @@
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
@@ -372,15 +375,7 @@
-
-
-
-
- 1740505390205
-
-
-
- 1740505390205
+
@@ -766,7 +761,15 @@
1743052111988
-
+
+
+ 1743106796406
+
+
+
+ 1743106796406
+
+
@@ -813,7 +816,6 @@
-
@@ -838,7 +840,8 @@
-
+
+
diff --git a/src/pages/tools/time/time-between-dates/service.ts b/src/pages/tools/time/time-between-dates/service.ts
index be1a5ac..785f392 100644
--- a/src/pages/tools/time/time-between-dates/service.ts
+++ b/src/pages/tools/time/time-between-dates/service.ts
@@ -119,35 +119,11 @@ export const formatTimeWithLargestUnit = (
difference: TimeDifference,
largestUnit: TimeUnit
): string => {
- const conversionFactors: Record = {
- years: 365.2425, // Leap years considered
- months: 30.436875, // Average month length
- days: 24, // Hours per day
- hours: 60, // Minutes per hour
- minutes: 60, // Seconds per minute
- seconds: 1000, // Milliseconds per second
- milliseconds: 1
- };
-
const largestUnitIndex = unitHierarchy.indexOf(largestUnit);
const unitsToInclude = unitHierarchy.slice(largestUnitIndex);
- // Deep copy to avoid mutating original object
- const convertedDifference = { ...difference };
+ // Preserve only whole values, do not apply fractional conversions
+ const adjustedDifference: TimeDifference = { ...difference };
- let carryOver = 0;
- for (let i = 0; i < largestUnitIndex; i++) {
- const unit = unitHierarchy[i];
- const nextUnit = unitHierarchy[i + 1];
-
- if (nextUnit) {
- carryOver =
- (convertedDifference[unit] || 0) * (conversionFactors[unit] || 1);
- convertedDifference[nextUnit] =
- (convertedDifference[nextUnit] || 0) + carryOver;
- convertedDifference[unit] = 0;
- }
- }
-
- return formatTimeDifference(convertedDifference, unitsToInclude);
+ return formatTimeDifference(adjustedDifference, unitsToInclude);
};
diff --git a/src/pages/tools/time/time-between-dates/time-between-dates.service.test.ts b/src/pages/tools/time/time-between-dates/time-between-dates.service.test.ts
new file mode 100644
index 0000000..5a8db7f
--- /dev/null
+++ b/src/pages/tools/time/time-between-dates/time-between-dates.service.test.ts
@@ -0,0 +1,96 @@
+import { describe, expect, it } from 'vitest';
+import {
+ calculateTimeBetweenDates,
+ formatTimeDifference,
+ formatTimeWithLargestUnit,
+ getTimeWithTimezone
+} from './service';
+
+// Utility function to create a date
+const createDate = (
+ year: number,
+ month: number,
+ day: number,
+ hours = 0,
+ minutes = 0,
+ seconds = 0
+) => new Date(Date.UTC(year, month - 1, day, hours, minutes, seconds));
+describe('calculateTimeBetweenDates', () => {
+ it('should calculate the correct time difference', () => {
+ const startDate = createDate(2023, 1, 1);
+ const endDate = createDate(2024, 1, 1);
+ const result = calculateTimeBetweenDates(startDate, endDate);
+
+ expect(result.years).toBe(1);
+ expect(result.months).toBe(12);
+ expect(result.days).toBeGreaterThanOrEqual(365);
+ });
+
+ it('should swap dates if startDate is after endDate', () => {
+ const startDate = createDate(2024, 1, 1);
+ const endDate = createDate(2023, 1, 1);
+ const result = calculateTimeBetweenDates(startDate, endDate);
+ expect(result.years).toBe(1);
+ });
+});
+
+describe('formatTimeDifference', () => {
+ it('should format time difference correctly', () => {
+ const difference = {
+ years: 1,
+ months: 2,
+ days: 10,
+ hours: 5,
+ minutes: 30,
+ seconds: 0,
+ milliseconds: 0
+ };
+ expect(formatTimeDifference(difference)).toBe(
+ '1 years, 2 months, 10 days, 5 hours, 30 minutes'
+ );
+ });
+
+ it('should return 0 seconds if all values are zero', () => {
+ expect(
+ formatTimeDifference({
+ years: 0,
+ months: 0,
+ days: 0,
+ hours: 0,
+ minutes: 0,
+ seconds: 0,
+ milliseconds: 0
+ })
+ ).toBe('0 seconds');
+ });
+});
+
+describe('getTimeWithTimezone', () => {
+ it('should convert UTC date to specified timezone', () => {
+ const date = getTimeWithTimezone('2025-03-27', '12:00:00', 'GMT+2');
+ expect(date.getUTCHours()).toBe(10); // 12:00 GMT+2 is 10:00 UTC
+ });
+
+ it('should throw error for invalid timezone', () => {
+ expect(() =>
+ getTimeWithTimezone('2025-03-27', '12:00:00', 'INVALID')
+ ).toThrow('Invalid timezone format');
+ });
+});
+
+describe('formatTimeWithLargestUnit', () => {
+ it('should format time with the largest unit', () => {
+ const difference = {
+ years: 0,
+ months: 1,
+ days: 15,
+ hours: 12,
+ minutes: 0,
+ seconds: 0,
+ milliseconds: 0
+ };
+ expect(formatTimeWithLargestUnit(difference, 'days')).toContain(
+ '15 days, 12 hours'
+ );
+ });
+});