angular / components

Component infrastructure and Material Design components for Angular
https://material.angular.io
MIT License
24.33k stars 6.73k forks source link

bug(mat-date-picker): the native date adapter can't detect first day of week from user locale #23073

Open evil-shrike opened 3 years ago

evil-shrike commented 3 years ago

Reproduction

All material datepickers display weeks starting Sunday while I have Russia locale set up which demands Monday is the first day of week:

image

Yes, I know I can globally change starting day via DateAdapter but I need to datepickers to be users' locale compatible.

Expected Behavior

Monday is first day of week

Actual Behavior

Sunday is first day of week.

Environment

crisbeto commented 3 years ago

I think that we haven't implemented this, because the browser doesn't have an API that exposes the first day of the week based on the user's locale.

evil-shrike commented 3 years ago

I see. That's bad. But then I'd suggest using international standard ISO 8601 (Monday as first day of week) as default.

wagnermaciel commented 3 years ago

We should be able to get this information from Angular's i18n system

PowerKiKi commented 3 years ago

According to the latest official CLDR data, there are 76 territories using Monday as first day of the week in a calendar page view, against 56 using Sunday. While this does not take into account the quantity of Angular app users that each of those territories represent, that still seems a good indicator that Monday might be a default value that is expected by more people.

See https://github.com/unicode-org/cldr/blob/master/common/supplemental/supplementalData.xml#L4693-L4741

Also see discussion about how to make this information available in browsers: https://github.com/tc39/ecma402/issues/6

morojenoe commented 3 years ago

We should be able to get this information from Angular's i18n system

@wagnermaciel can we use getLocaleFirstDayOfWeek here?

ilyakonrad commented 3 weeks ago

What's the solution here?

PowerKiKi commented 3 weeks ago

@ilyakonrad, implement your own DateAdapter and implement getFirstDayOfWeek() according to your need. One simple way to that could be to override NativeDateAdapter, like so:

@Injectable({
    providedIn: 'root',
})
export class WeekAlwaysStartOnMondayDateAdapter extends NativeDateAdapter {
    public override getFirstDayOfWeek(): number {
        // Always starts on Monday, even though it is not true for Canada, U.S., Mexico and many more
        // Also see https://github.com/tc39/ecma402/issues/6
        return 1;
    }
}

Then in your main:

export const appConfig: ApplicationConfig = {
    providers: [
        {
            provide: DateAdapter,
            useClass: WeekAlwaysStartOnMondayDateAdapter,
        },
        // other things here...
    ],
};