-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DatePicker AdapterLuxon start day of the week with Sunday #12821
Comments
I have this same problem for an application I am working on. This appears to be an issue with how Luxon reports the days of week using Intl. The issue can be reproduced by calling the date adapter function https://github.com/dmtrKovalenko/date-io/blob/master/packages/luxon/src/luxon-utils.ts#L332
|
Any updates on this?? |
We have the same issue with Material UI and AdapterLuxon. I'd like to continue to use Luxon, but without being able to set the start of the week to Sunday. We'll have to abandon Luxon for another package. We get a ton of user complaints about the date picker's calendar layout. |
@patrickclancy you can override the import React, { PropsWithChildren } from 'react';
import { AdapterLuxon } from '@mui/x-date-pickers/AdapterLuxon';
import { DateTime } from 'luxon';
import { LocalizationProvider } from '@mui/x-date-pickers';
class Adapter extends AdapterLuxon {
public getWeekdays = () => {
return ['S', 'M', 'T', 'W', 'T', 'F', 'S'];
};
getWeekArray = (date: DateTime) => {
const { days } = date
.endOf('month')
.endOf('week')
.diff(date.startOf('month').startOf('week'), 'days')
.toObject();
let weeks: DateTime[][] = [];
new Array(Math.round(days ?? 0))
.fill(0)
.map((_, i) => i)
.map(day =>
date
.startOf('month')
.startOf('week')
.minus({ days: 1 })
.plus({ days: day }),
)
.forEach((v, i) => {
if (i === 0 || (i % 7 === 0 && i > 6)) {
weeks.push([v]);
return;
}
weeks[weeks.length - 1].push(v);
});
weeks = weeks.filter(week => {
// do not allow weeks with start or end outside of current month
return (
week[0].hasSame(date, 'month') ||
week[week.length - 1].hasSame(date, 'month')
);
});
return weeks;
};
}
export const DatePickerProvider: React.FC<PropsWithChildren> = ({
children,
}) => (
<LocalizationProvider dateAdapter={Adapter}>
{children}
</LocalizationProvider>
); Then you can just wrap your app with |
Concerning |
Until Luxon supports the change of the start-week day, I'm want to share the solution that works for me even with five-weeks months cases: import AdapterLuxon from '@mui/lab/AdapterLuxon';
import { DateTime } from 'luxon';
const DAYS_ON_WEEK = 7;
/**
* Luxon adapter for the `LocalizationProvider` component to set the sunday as first day of the week.
*/
export class CustomLuxonAdapter extends AdapterLuxon {
/** Set the order of the labels in a week. */
getWeekdays = () => {
return ['S', 'M', 'T', 'W', 'T', 'F', 'S'];
};
/** Generate the dates per month. */
getWeekArray = (initial: DateTime) => {
const monthStart = initial.startOf('month').startOf('week');
const monthEnd = initial.endOf('month').endOf('week');
const range = monthStart.diff(monthEnd);
const weeks = Math.round(Math.abs(range.as('weeks'))) + 1;
const days = weeks * DAYS_ON_WEEK;
const month: DateTime[][] = [];
for (let index = 0; index < days; index++) {
const week = month.length - 1;
const date = initial
.startOf('month')
.startOf('week')
.plus({ day: index - 1 });
if (index === 0 || index % 7 === 0) {
month.push([date]);
continue;
}
month[week] = [...month[week], date];
}
return month;
};
}
|
My team has this issue too, implementing @sam-woodridge 's solution (thank you!) However, this is almost table-stakes for us. It would be great to get this handled |
Here's a date adapter that accepts any day (1-7) as the start-of-week. The factory pattern allows us to change the start-of-week mid-session, when the user selects a different locale. function adapterLuxonFactory(weekStartsOn: number) {
class Adapter extends AdapterLuxon {
private weekStartsOn = weekStartsOn;
/** Controls the header of the calendar month view. */
public getWeekdays = () => {
const weekdays = Info.weekdaysFormat("narrow", { locale: this.locale });
const start = weekdays.slice(0, this.weekStartsOn - 1);
const end = weekdays.slice(this.weekStartsOn - 1);
return [...end, ...start];
};
/** Controls the day buttons of the calendar month view. */
getWeekArray = (date: DateTime) => {
const startOfMonth = date.startOf("month");
const endOfMonth = date.endOf("month");
const firstDayOfMonth = startOfMonth.weekday;
const startOfWeek = startOfMonth.minus({
days: (firstDayOfMonth - this.weekStartsOn + 7) % 7,
});
const endOfWeek = endOfMonth
.plus({ days: 6 - endOfMonth.weekday + this.weekStartsOn })
.endOf("day");
const { days } = endOfWeek.diff(startOfWeek, "days").toObject();
const weeks: DateTime[][] = [];
new Array<number>(Math.round(days ?? 0))
.fill(0)
.map((_, i) => i)
.map((day) => startOfWeek.plus({ days: day }))
.forEach((v, i) => {
if (i === 0 || (i % 7 === 0 && i > 6)) {
weeks.push([v]);
return;
}
weeks[weeks.length - 1].push(v);
});
return weeks;
};
}
return Adapter;
}
export function LocalizationProvider({
children,
}: {
children?: React.ReactNode;
}): JSX.Element {
const { weekStartsOn } = useYourOwnDatabase();
return (
<MuiLocalizationProvider dateAdapter={adapterLuxonFactory(weekStartsOn)}>
{children}
</MuiLocalizationProvider>
);
} This is built on @sam-woodridge 's solution. |
Thanks for your solution! I would just advise you to memoize the adapter because it is used in a lot of memoization processed inside the pickers. |
In case anyone stumbles upon this thread again, you can now set the first day of the week with Luxon. This code is straight from MUI's documentation:
Place this somewhere near the top of your React application (I put it in App.tsx). I set the firstDay to 7 (Sunday) and now all my MUI date pickers are displaying Sunday as the first day of the week. |
@flaviendelangle I've moved the issue to the MUI X repository. Could you verify if it's still relevant? |
@georgesglynn: How did we do? Your experience with our support team matters to us. If you have a moment, please share your thoughts in this short Support Satisfaction survey. |
Duplicates
Summary 💡
Hello! I am a dev at Southwest Airlines and we have absolutely LOVED using the MUI package for our team's application.
We are currently on V4, I am working towards getting us upgraded to V5. This particular issue has been around for us since early last year but now that the DatePicker is under the lab package and I am currently working on migrating our implementation with https://material-ui-pickers.dev/ to the lab package I figure this would be a good time to bring this up.
Today, if you use the DatePicker component with the AdapterLuxon component as the LocalizationProvider, the week by default starts with Monday.
I tried to look into the AdapterLuxon code myself to see if I could customize it directly for our use case but I could not figure it out. Any guidance on this would be greatly appreciated!
Examples 🌈
Screenshots for clarity:
(AdapterLuxon)
(AdapterDateFns)
Motivation 🔦
Our customers require this calendar to start with Sunday, but this component provides no customization to change this. That is my feature request, to add a prop to the DatePicker component that would allow you to change the starting day of the week.
Today since we primarily use Luxon, we have to convert every Luxon date that interacts with this DatePicker component to DateFns and use the AdapterDateFns in order to have the calendar start each week with Sunday. It is a lot of overhead/messy work.
Search keywords:
The text was updated successfully, but these errors were encountered: