Skip to content
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

[pickers] fix the issue of the timezone change in Day calendar #12256

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
9b9527d
fix the issue of the timezone change in Day calendar
shaharyar-shamshi Feb 28, 2024
e478c89
utils divided
shaharyar-shamshi Feb 29, 2024
82c4346
utils divided
shaharyar-shamshi Feb 29, 2024
33f17cc
test case for jalali added
shaharyar-shamshi Feb 29, 2024
c873b53
merged
shaharyar-shamshi Feb 29, 2024
0579906
unit test cases for date adapter added
shaharyar-shamshi Feb 29, 2024
d7796b4
unit test cases for date adapter added
shaharyar-shamshi Feb 29, 2024
b422eeb
Merge branch 'next' into hotfix/DatePicker-timezone
shaharyar-shamshi Mar 1, 2024
2b6be0c
jalali test case added
shaharyar-shamshi Mar 1, 2024
4452035
jalali test case added
shaharyar-shamshi Mar 1, 2024
3577af2
datefns test case added
shaharyar-shamshi Mar 1, 2024
8efbf84
datefns test case added
shaharyar-shamshi Mar 1, 2024
00887cc
adding e2e test case for the timezone change
shaharyar-shamshi Mar 1, 2024
eacbc67
adding e2e test case for the timezone change
shaharyar-shamshi Mar 1, 2024
c282d60
adding e2e test case for the timezone change
shaharyar-shamshi Mar 1, 2024
7dac6a4
adding e2e test case for the timezone change
shaharyar-shamshi Mar 1, 2024
b8f987c
intentionally fail
shaharyar-shamshi Mar 1, 2024
8f908ff
intentionally fail remove
shaharyar-shamshi Mar 1, 2024
28b0bad
date range calendar e2e test case
shaharyar-shamshi Mar 1, 2024
c80a0e6
date range calendar e2e test case
shaharyar-shamshi Mar 1, 2024
72eae56
date range calendar e2e test case
shaharyar-shamshi Mar 1, 2024
dca0d17
offset added
shaharyar-shamshi Mar 2, 2024
6f71e8e
comment added
shaharyar-shamshi Mar 2, 2024
4da767d
test case improved
shaharyar-shamshi Mar 2, 2024
71aa9bf
test case improved
shaharyar-shamshi Mar 2, 2024
b7122a7
test case improved
shaharyar-shamshi Mar 3, 2024
a340814
test case improved
shaharyar-shamshi Mar 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import { DateRangePickerDay } from '@mui/x-date-pickers-pro/DateRangePickerDay';
import { describeConformance } from 'test/utils/describeConformance';
import { DateRangePosition } from './DateRangeCalendar.types';

const TIMEZONE_TO_TEST = ['UTC', 'system', 'America/New_York'];

const getPickerDay = (name: string, picker = 'January 2018') =>
getByRole(screen.getByText(picker)?.parentElement?.parentElement!, 'gridcell', { name });

Expand Down Expand Up @@ -564,4 +566,89 @@ describe('<DateRangeCalendar />', () => {
expect(RenderCount.callCount - renderCountBeforeChange).to.equal(6); // 2 render * 3 day
});
});

TIMEZONE_TO_TEST.forEach((timezone) => {
describe(`timezone change from utc to ${timezone}`, () => {
it('on timezone change the rendered UI should display the Calendar of same month', () => {
// Render the component with initial timezone prop
const { rerender } = render(<DateRangeCalendar timezone="UTC" />);

// Create a map of buttons with their indices for the initial render
const renderButtonsMap = {};
screen.getAllByRole('gridcell').forEach((element, index) => {
if (element.tagName.toLowerCase() === 'button' && element && element.textContent) {
const numberMatch = element.textContent.trim().match(/\d+/);
if (numberMatch) {
const number = parseInt(numberMatch[0], 10);
renderButtonsMap[index] = number;
}
}
});

// Rerender the component with a different timezone prop
rerender(<DateRangeCalendar timezone={timezone} />);

// Create a map of buttons with their indices for the rerender
const reRenderButtonsMap = {};

screen.getAllByRole('gridcell').forEach((element, index) => {
if (element.tagName.toLowerCase() === 'button' && element && element.textContent) {
const numberMatch = element.textContent.trim().match(/\d+/);
if (numberMatch) {
const number = parseInt(numberMatch[0], 10);
reRenderButtonsMap[index] = number;
}
}
});

// Ensure the number of buttons and their numbers are consistent
expect(Object.keys(reRenderButtonsMap).length).equals(Object.keys(renderButtonsMap).length);
Object.keys(renderButtonsMap).forEach((index) => {
expect(reRenderButtonsMap[index]).equals(renderButtonsMap[index]);
});
});

it('should select the range from the next month', () => {
const { rerender } = render(
<DateRangeCalendar
timezone="UTC"
defaultValue={[adapterToUse.date('2019-01-01'), null]}
/>,
);

fireEvent.click(getPickerDay('10', 'January 2019'));
fireEvent.click(getPickerDay('19', 'February 2019'));

const renderButtons = screen
.getAllByRole('gridcell')
.filter((button) => button.tagName.toLowerCase() === 'button');

const selectedStartDateButton = renderButtons.findIndex(
(button) => button.dataset.position === 'start',
);

const selectedEndDateButton = renderButtons.findIndex(
(button) => button.dataset.position === 'end',
);

rerender(
<DateRangeCalendar
timezone={timezone}
defaultValue={[adapterToUse.date('2019-01-01'), null]}
/>,
);

const rerenderedStartDateButton = renderButtons.findIndex(
(button) => button.dataset.position === 'start',
);

const rerenderedEndDateButton = renderButtons.findIndex(
(button) => button.dataset.position === 'end',
);

expect(Math.abs(selectedStartDateButton - rerenderedStartDateButton)).lessThanOrEqual(1);
expect(Math.abs(selectedEndDateButton - rerenderedEndDateButton)).lessThanOrEqual(1);
});
});
});
});
25 changes: 25 additions & 0 deletions packages/x-date-pickers/src/AdapterDateFns/AdapterDateFns.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,29 @@ describe('<AdapterDateFns />', () => {
});
});
});

describe('Test setMonthYearDate', () => {
const { render, clock, adapter } = createPickerRenderer({
clock: 'fake',
adapterName: 'date-fns',
locale: enUS,
});

const { renderWithProps } = buildFieldInteractions({
render,
clock,
Component: DateTimeField,
});

it('should set month, year, and date correctly', () => {
const initialDate = adapter.date('2022-01-15T09:35:00')!;
const newDate = adapter.setMonthYearDate(initialDate, 1400, 0, 25);

const v7Response = renderWithProps({
enableAccessibleFieldDOMStructure: true,
value: newDate,
});
expectFieldValueV7(v7Response.getSectionsContainer(), '01/25/1400 09:35 AM');
});
});
});
4 changes: 4 additions & 0 deletions packages/x-date-pickers/src/AdapterDateFns/AdapterDateFns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -327,4 +327,8 @@ export class AdapterDateFns

return years;
};

public setMonthYearDate = (value: Date, year: number, month: number, date: number) => {
return setDate(setMonth(setYear(value, year), month), date);
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,29 @@ describe('<AdapterDateFnsJalali />', () => {
});
});
});

describe('Test setMonthYearDate', () => {
const { render, clock, adapter } = createPickerRenderer({
clock: 'fake',
adapterName: 'date-fns-jalali',
locale: enUS,
});

const { renderWithProps } = buildFieldInteractions({
render,
clock,
Component: DateTimeField,
});

it('should set month, year, and date correctly', () => {
const initialDate = adapter.date('2022-01-15T09:35:00')!;
const newDate = adapter.setMonthYearDate(initialDate, 1400, 0, 25);

const v7Response = renderWithProps({
enableAccessibleFieldDOMStructure: true,
value: newDate,
});
expectFieldValueV7(v7Response.getSectionsContainer(), '01/25/1400 09:35 AM');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -519,4 +519,8 @@ export class AdapterDateFnsJalali implements MuiPickersAdapter<Date, DateFnsLoca

return years;
};

public setMonthYearDate = (value: Date, year: number, month: number, date: number) => {
return setDate(setMonth(setYear(value, year), month), date);
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -334,4 +334,8 @@ export class AdapterDateFns

return years;
};

public setMonthYearDate = (value: Date, year: number, month: number, date: number) => {
return setDate(setMonth(setYear(value, year), month), date);
};
}
26 changes: 26 additions & 0 deletions packages/x-date-pickers/src/AdapterDayjs/AdapterDayjs.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -155,5 +155,31 @@ describe('<AdapterDayjs />', () => {
});
});
});

describe('Test setMonthYearDate', () => {
const localeObject = { code: 'en' };
const { render, clock, adapter } = createPickerRenderer({
clock: 'fake',
adapterName: 'dayjs',
locale: localeObject,
});

const { renderWithProps } = buildFieldInteractions({
render,
clock,
Component: DateTimeField,
});

it('should set month, year, and date correctly', () => {
const initialDate = adapter.date('2022-01-15T09:35:00')!;
const newDate = adapter.setMonthYearDate(initialDate, 1400, 4, 25);

const v7Response = renderWithProps({
enableAccessibleFieldDOMStructure: true,
value: newDate,
});
expectFieldValueV7(v7Response.getSectionsContainer(), '05/25/1400 09:35 AM');
});
});
});
});
4 changes: 4 additions & 0 deletions packages/x-date-pickers/src/AdapterDayjs/AdapterDayjs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -677,4 +677,8 @@ export class AdapterDayjs implements MuiPickersAdapter<Dayjs, string> {

return years;
};

public setMonthYearDate = (value: Dayjs, year: number, month: number, date: number) => {
return this.adjustOffset(value.set('year', year).set('month', month).set('date', date));
};
}
26 changes: 26 additions & 0 deletions packages/x-date-pickers/src/AdapterLuxon/AdapterLuxon.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -188,5 +188,31 @@ describe('<AdapterLuxon />', () => {
});
});
});

describe('Test setMonthYearDate', () => {
const localeObject = { code: 'en' };
const { render, clock, adapter } = createPickerRenderer({
clock: 'fake',
adapterName: 'luxon',
locale: localeObject,
});

const { renderWithProps } = buildFieldInteractions({
render,
clock,
Component: DateTimeField,
});

it('should set month, year, and date correctly', () => {
const initialDate = adapter.date('2022-01-15T09:35:00')!;
const newDate = adapter.setMonthYearDate(initialDate, 1400, 0, 25);

const v7Response = renderWithProps({
enableAccessibleFieldDOMStructure: true,
value: newDate,
});
expectFieldValueV7(v7Response.getSectionsContainer(), '01/25/1400 09:35 AM');
});
});
});
});
6 changes: 6 additions & 0 deletions packages/x-date-pickers/src/AdapterLuxon/AdapterLuxon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -499,4 +499,10 @@ export class AdapterLuxon implements MuiPickersAdapter<DateTime, string> {

return years;
};

public setMonthYearDate = (value: DateTime, year: number, month: number, date: number) => {
// See https://github.com/moment/luxon/blob/master/docs/moment.md#major-functional-differences
// also refer getMonth() method it returns -1 month
return value.set({ year, month: month + 1, day: date });
};
}
26 changes: 26 additions & 0 deletions packages/x-date-pickers/src/AdapterMoment/AdapterMoment.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -188,4 +188,30 @@ describe('<AdapterMoment />', () => {
adapter.date()!;
expect(spiedInstance.callCount).to.equal(1);
});

describe('Test setMonthYearDate', () => {
const localeObject = { code: 'en' };
const { render, clock, adapter } = createPickerRenderer({
clock: 'fake',
adapterName: 'moment',
locale: localeObject,
});

const { renderWithProps } = buildFieldInteractions({
render,
clock,
Component: DateTimeField,
});

it('should set month, year, and date correctly', () => {
const initialDate = adapter.date('2022-01-15T09:35:00')!;
const newDate = adapter.setMonthYearDate(initialDate, 1400, 0, 25);

const v7Response = renderWithProps({
enableAccessibleFieldDOMStructure: true,
value: newDate,
});
expectFieldValueV7(v7Response.getSectionsContainer(), '01/25/1400 09:35 AM');
});
});
});
4 changes: 4 additions & 0 deletions packages/x-date-pickers/src/AdapterMoment/AdapterMoment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -557,4 +557,8 @@ export class AdapterMoment implements MuiPickersAdapter<Moment, string> {

return years;
}

public setMonthYearDate = (value: Moment, year: number, month: number, date: number) => {
return value.year(year).month(month).date(date);
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,5 +93,31 @@ describe('<AdapterMomentHijri />', () => {
});
});
});

describe('Test setMonthYearDate', () => {
const localeObject = { code: 'ar' };
const { render, clock, adapter } = createPickerRenderer({
clock: 'fake',
adapterName: 'moment-hijri',
locale: localeObject,
});

const { renderWithProps } = buildFieldInteractions({
render,
clock,
Component: DateTimeField,
});

it('should set month, year, and date correctly', () => {
const initialDate = adapter.date('2022-01-15T09:35:00')!;
const newDate = adapter.setMonthYearDate(initialDate, 1439, 4, 15);

const v7Response = renderWithProps({
enableAccessibleFieldDOMStructure: true,
value: newDate,
});
expectFieldValueV7(v7Response.getSectionsContainer(), '١٤٣٩/٠٥/١٥ ٠٩:٣٥');
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -238,4 +238,8 @@ export class AdapterMomentHijri extends AdapterMoment implements MuiPickersAdapt

return super.getYearRange([start, end]);
};

public setMonthYearDate = (value: Moment, year: number, month: number, date: number) => {
return value.clone().iYear(year).iMonth(month).iDate(date);
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,30 @@ describe('<AdapterMomentJalaali />', () => {
});
});
});

describe('Test setMonthYearDate', () => {
const localeObject = { code: 'en' };
const { render, clock, adapter } = createPickerRenderer({
clock: 'fake',
adapterName: 'moment-jalaali',
locale: localeObject,
});

const { renderWithProps } = buildFieldInteractions({
render,
clock,
Component: DateTimeField,
});

it('should set month, year, and date correctly', () => {
const initialDate = adapter.date('2022-01-15T09:35:00')!;
const newDate = adapter.setMonthYearDate(initialDate, 1400, 0, 25);

const v7Response = renderWithProps({
enableAccessibleFieldDOMStructure: true,
value: newDate,
});
expectFieldValueV7(v7Response.getSectionsContainer(), '1400/01/25 09:35');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -247,4 +247,8 @@ export class AdapterMomentJalaali
public getWeekNumber = (value: Moment) => {
return value.jWeek();
};

public setMonthYearDate = (value: Moment, year: number, month: number, date: number): Moment => {
return value.clone().jYear(year).jMonth(month).jDate(date);
};
}
Loading
Loading