diff --git a/packages/react-calendar/README.md b/packages/react-calendar/README.md
index b949eaff..71b03991 100644
--- a/packages/react-calendar/README.md
+++ b/packages/react-calendar/README.md
@@ -147,6 +147,7 @@ Displays a complete, interactive calendar.
| tileDisabled | Pass a function to determine if a certain day should be displayed as disabled. | n/a | `({ activeStartDate, date, view }) => date.getDay() === 0` |
| value | Calendar value. Can be either one value or an array of two values. If you wish to use react-calendar in an uncontrolled way, use `defaultValue` instead. | n/a |
- Date: `new Date()`
- String: `2017-01-01`
- An array of dates: `[new Date(2017, 0, 1), new Date(2017, 7, 1)]`
- An array of strings: `['2017-01-01', '2017-08-01']`
|
| view | Determines which calendar view shall be opened. Does not disable navigation. Can be `"month"`, `"year"`, `"decade"` or `"century"`. If you wish to use react-calendar in an uncontrolled way, use `defaultView` instead. | The most detailed view allowed | `"year"` |
+| now | Current date used as now, allows to display an offsetted time as today | `new Date()` |
### MonthView, YearView, DecadeView, CenturyView
diff --git a/packages/react-calendar/src/Calendar.tsx b/packages/react-calendar/src/Calendar.tsx
index a9aa6745..88de7a52 100644
--- a/packages/react-calendar/src/Calendar.tsx
+++ b/packages/react-calendar/src/Calendar.tsx
@@ -419,6 +419,13 @@ export type CalendarProps = {
* @example 'year'
*/
view?: View;
+ /**
+ * Determines which date to show as the current date on the calendar
+ *
+ * @default new Date()
+ * @example 'year'
+ */
+ now?: Date;
};
function toDate(value: Date | string): Date {
@@ -656,6 +663,7 @@ const Calendar: React.ForwardRefExoticComponent(
@@ -1024,6 +1032,7 @@ const Calendar: React.ForwardRefExoticComponent, 'classes' | 'currentDecade' | 'date'>;
export default function Years(props: YearsProps): React.ReactElement {
- const { activeStartDate, hover, showNeighboringDecade, value, valueType, ...otherProps } = props;
+ const { activeStartDate, hover, showNeighboringDecade, value, valueType, now, ...otherProps } = props;
const start = getBeginOfDecadeYear(activeStartDate);
const end = start + (showNeighboringDecade ? 11 : 9);
@@ -50,6 +50,7 @@ export default function Years(props: YearsProps): React.ReactElement {
start={start}
value={value}
valueType={valueType}
+ now={now}
/>
);
}
diff --git a/packages/react-calendar/src/MonthView.tsx b/packages/react-calendar/src/MonthView.tsx
index d75fc796..69f9de49 100644
--- a/packages/react-calendar/src/MonthView.tsx
+++ b/packages/react-calendar/src/MonthView.tsx
@@ -34,6 +34,13 @@ type MonthViewProps = {
* @example true
*/
showWeekNumbers?: boolean;
+ /**
+ * Determines which date to show as the current date on the calendar
+ *
+ * @default new Date()
+ * @example 'year'
+ */
+ now?: Date;
} & Omit<
React.ComponentProps &
React.ComponentProps &
@@ -52,6 +59,7 @@ export default function MonthView(props: MonthViewProps): React.ReactElement {
formatWeekday,
onClickWeekNumber,
showWeekNumbers,
+ now,
...childProps
} = props;
@@ -63,6 +71,7 @@ export default function MonthView(props: MonthViewProps): React.ReactElement {
formatWeekday={formatWeekday}
locale={locale}
onMouseLeave={onMouseLeave}
+ now={now}
/>
);
}
@@ -84,7 +93,7 @@ export default function MonthView(props: MonthViewProps): React.ReactElement {
}
function renderDays() {
- return ;
+ return ;
}
const className = 'react-calendar__month-view';
diff --git a/packages/react-calendar/src/MonthView/Days.tsx b/packages/react-calendar/src/MonthView/Days.tsx
index 7030b406..3e03439c 100644
--- a/packages/react-calendar/src/MonthView/Days.tsx
+++ b/packages/react-calendar/src/MonthView/Days.tsx
@@ -49,6 +49,7 @@ export default function Days(props: DaysProps): React.ReactElement {
showNeighboringMonth,
value,
valueType,
+ now,
...otherProps
} = props;
@@ -118,6 +119,7 @@ export default function Days(props: DaysProps): React.ReactElement {
start={start}
value={value}
valueType={valueType}
+ now={now}
/>
);
}
diff --git a/packages/react-calendar/src/MonthView/Weekdays.tsx b/packages/react-calendar/src/MonthView/Weekdays.tsx
index 1a911039..5a849698 100644
--- a/packages/react-calendar/src/MonthView/Weekdays.tsx
+++ b/packages/react-calendar/src/MonthView/Weekdays.tsx
@@ -40,6 +40,13 @@ type WeekdaysProps = {
*/
locale?: string;
onMouseLeave?: () => void;
+ /**
+ * Determines which date to show as the current date on the calendar
+ *
+ * @default new Date()
+ * @example 'year'
+ */
+ now?: Date;
};
export default function Weekdays(props: WeekdaysProps): React.ReactElement {
@@ -49,6 +56,7 @@ export default function Weekdays(props: WeekdaysProps): React.ReactElement {
formatWeekday = defaultFormatWeekday,
locale,
onMouseLeave,
+ now,
} = props;
const anyDate = new Date();
@@ -72,7 +80,7 @@ export default function Weekdays(props: WeekdaysProps): React.ReactElement {
key={weekday}
className={clsx(
weekdayClassName,
- isCurrentDayOfWeek(weekdayDate) && `${weekdayClassName}--current`,
+ isCurrentDayOfWeek(weekdayDate, now) && `${weekdayClassName}--current`,
isWeekend(weekdayDate, calendarType) && `${weekdayClassName}--weekend`,
)}
>
diff --git a/packages/react-calendar/src/TileGroup.tsx b/packages/react-calendar/src/TileGroup.tsx
index d5735f99..08efa7eb 100644
--- a/packages/react-calendar/src/TileGroup.tsx
+++ b/packages/react-calendar/src/TileGroup.tsx
@@ -17,6 +17,7 @@ type TileGroupProps = {
step?: number;
value?: Value;
valueType: RangeType;
+ now?: Date;
};
export default function TileGroup({
@@ -32,6 +33,7 @@ export default function TileGroup({
step = 1,
value,
valueType,
+ now,
}: TileGroupProps): React.ReactElement {
const tiles = [];
for (let point = start; point <= end; point += step) {
@@ -45,6 +47,7 @@ export default function TileGroup({
hover,
value,
valueType,
+ now,
}),
date,
}),
diff --git a/packages/react-calendar/src/YearView/Months.tsx b/packages/react-calendar/src/YearView/Months.tsx
index 77d55509..f75a6125 100644
--- a/packages/react-calendar/src/YearView/Months.tsx
+++ b/packages/react-calendar/src/YearView/Months.tsx
@@ -17,7 +17,7 @@ type MonthsProps = {
Omit, 'classes' | 'date'>;
export default function Months(props: MonthsProps): React.ReactElement {
- const { activeStartDate, hover, value, valueType, ...otherProps } = props;
+ const { activeStartDate, hover, value, valueType, now, ...otherProps } = props;
const start = 0;
const end = 11;
const year = getYear(activeStartDate);
@@ -45,6 +45,7 @@ export default function Months(props: MonthsProps): React.ReactElement {
start={start}
value={value}
valueType={valueType}
+ now={now}
/>
);
}
diff --git a/packages/react-calendar/src/shared/dates.ts b/packages/react-calendar/src/shared/dates.ts
index 5e03be19..bfd670d5 100644
--- a/packages/react-calendar/src/shared/dates.ts
+++ b/packages/react-calendar/src/shared/dates.ts
@@ -393,10 +393,11 @@ export function getDecadeLabel(
* Returns a boolean determining whether a given date is the current day of the week.
*
* @param {Date} date Date.
+ * @param {Date} now optional defaults to new Date()
* @returns {boolean} Whether a given date is the current day of the week.
*/
-export function isCurrentDayOfWeek(date: Date): boolean {
- return date.getDay() === new Date().getDay();
+export function isCurrentDayOfWeek(date: Date, now?: Date): boolean {
+ return date.getDay() === (now ?? new Date()).getDay();
}
/**
diff --git a/packages/react-calendar/src/shared/utils.ts b/packages/react-calendar/src/shared/utils.ts
index 888f0418..2b6384ea 100644
--- a/packages/react-calendar/src/shared/utils.ts
+++ b/packages/react-calendar/src/shared/utils.ts
@@ -79,6 +79,7 @@ export function getTileClasses(args: {
hover?: Date | null;
value?: Value;
valueType?: RangeType;
+ now?: Date;
}): string[] {
if (!args) {
throw new Error('args is required');
@@ -93,7 +94,7 @@ export function getTileClasses(args: {
return classes;
}
- const now = new Date();
+ const now = args.now ?? new Date();
const dateRange = (() => {
if (Array.isArray(date)) {
return date;
diff --git a/test/Test.tsx b/test/Test.tsx
index 820ca6ed..149407e3 100644
--- a/test/Test.tsx
+++ b/test/Test.tsx
@@ -15,7 +15,10 @@ import './Test.css';
import type { LooseValue, Value, View } from './shared/types.js';
-const now = new Date();
+// Now can be changed to test the calendar in a different instant
+// const now = new Date();
+
+const now = new Date(2024, 7, 31);
const tileClassName = ({ date, view }: { date: Date; view: View }) => {
switch (view) {
@@ -122,6 +125,7 @@ export default function Test() {
className: 'myCustomCalendarClassName',
locale,
maxDate,
+ now,
maxDetail,
minDate,
minDetail,