diff --git a/packages/vant/src/calendar/CalendarDay.tsx b/packages/vant/src/calendar/CalendarDay.tsx
index 9673e09ab64..f3c97e0ffcb 100644
--- a/packages/vant/src/calendar/CalendarDay.tsx
+++ b/packages/vant/src/calendar/CalendarDay.tsx
@@ -5,7 +5,7 @@ import {
type CSSProperties,
} from 'vue';
import { makeNumberProp, createNamespace, makeRequiredProp } from '../utils';
-import { bem } from './utils';
+import { bem, isLastRowInMonth } from './utils';
import type { CalendarDayItem } from './types';
const [name] = createNamespace('calendar-day');
@@ -54,7 +54,7 @@ export default defineComponent({
}
}
- if (offset + (item.date?.getDate() || 1) > 28) {
+ if (item.date && isLastRowInMonth(item.date, offset)) {
style.marginBottom = 0;
}
diff --git a/packages/vant/src/calendar/test/__snapshots__/index.spec.ts.snap b/packages/vant/src/calendar/test/__snapshots__/index.spec.ts.snap
index 8025cd9df9f..693b2de4d86 100644
--- a/packages/vant/src/calendar/test/__snapshots__/index.spec.ts.snap
+++ b/packages/vant/src/calendar/test/__snapshots__/index.spec.ts.snap
@@ -202,49 +202,42 @@ exports[`formatter prop 1`] = `
24
25
26
27
28
29
30
@@ -510,49 +503,42 @@ exports[`popup wrapper 2`] = `
24
25
26
27
28
29
30
@@ -811,49 +797,42 @@ exports[`should render title、footer、subtitle slot correctly 1`] = `
24
25
26
27
28
29
30
diff --git a/packages/vant/src/calendar/test/__snapshots__/prop.spec.ts.snap b/packages/vant/src/calendar/test/__snapshots__/prop.spec.ts.snap
index 6b8d835992d..d746416afe8 100644
--- a/packages/vant/src/calendar/test/__snapshots__/prop.spec.ts.snap
+++ b/packages/vant/src/calendar/test/__snapshots__/prop.spec.ts.snap
@@ -195,49 +195,42 @@ exports[`lazy-render prop 1`] = `
24
25
26
27
28
29
30
diff --git a/packages/vant/src/calendar/test/utils.spec.ts b/packages/vant/src/calendar/test/utils.spec.ts
index 5e42340cd35..074f50b3229 100644
--- a/packages/vant/src/calendar/test/utils.spec.ts
+++ b/packages/vant/src/calendar/test/utils.spec.ts
@@ -1,4 +1,10 @@
-import { compareDay, compareMonth, getNextDay, calcDateNum } from '../utils';
+import {
+ compareDay,
+ compareMonth,
+ getNextDay,
+ calcDateNum,
+ isLastRowInMonth,
+} from '../utils';
const date1 = new Date(2010, 0, 1);
const date2 = new Date(2010, 0, 2);
@@ -29,3 +35,22 @@ test('calcDateNum', () => {
expect(calcDateNum([date1, date2])).toEqual(2);
expect(calcDateNum([date1, date3])).toEqual(32);
});
+
+test('isLastRowInMonth', () => {
+ // test first day of month
+ expect(isLastRowInMonth(new Date(2024, 0, 1), 0)).toEqual(false);
+
+ // test middle of month
+ expect(isLastRowInMonth(new Date(2024, 0, 22), 0)).toEqual(false);
+ expect(isLastRowInMonth(new Date(2024, 0, 28), 0)).toEqual(false);
+
+ // test last week of month
+ expect(isLastRowInMonth(new Date(2024, 0, 29), 0)).toEqual(true);
+ expect(isLastRowInMonth(new Date(2024, 0, 31), 0)).toEqual(true);
+
+ // test different offset
+ expect(isLastRowInMonth(new Date(2024, 0, 18), 4)).toEqual(false);
+ expect(isLastRowInMonth(new Date(2024, 0, 24), 4)).toEqual(false);
+ expect(isLastRowInMonth(new Date(2024, 0, 25), 4)).toEqual(true);
+ expect(isLastRowInMonth(new Date(2024, 0, 31), 4)).toEqual(true);
+});
diff --git a/packages/vant/src/calendar/utils.ts b/packages/vant/src/calendar/utils.ts
index 962b720df7e..8abe1dff39c 100644
--- a/packages/vant/src/calendar/utils.ts
+++ b/packages/vant/src/calendar/utils.ts
@@ -82,3 +82,17 @@ export function calcDateNum(date: [Date, Date]) {
const day2 = date[1].getTime();
return (day2 - day1) / (1000 * 60 * 60 * 24) + 1;
}
+
+/**
+ * Checks if the given date is in the last row of its month in a calendar view
+ * @param date The date to check
+ * @param offset The offset of the first day of the month
+ * @returns boolean indicating whether the date is in the last row
+ */
+export function isLastRowInMonth(date: Date, offset: number = 0) {
+ const lastDay = new Date(date.getFullYear(), date.getMonth() + 1, 0);
+ const currentPos = offset + date.getDate() - 1;
+ const lastDayPos = offset + lastDay.getDate() - 1;
+
+ return Math.floor(currentPos / 7) === Math.floor(lastDayPos / 7);
+}