diff --git a/BREAKING.md b/BREAKING.md
index 821ad7f28b..a7ac8778e8 100644
--- a/BREAKING.md
+++ b/BREAKING.md
@@ -86,6 +86,8 @@ This section details the desktop browser, JavaScript framework, and mobile platf
- Datetime no longer automatically adjusts the `value` property when passed an array and `multiple="false"`. Developers should update their apps to ensure they are using the API correctly.
+- Datetime no longer incorrectly reports the time zone when `value` is updated. Datetime does not manage time zones, so any time zone information provided is ignored.
+
- `ionChange` is no longer emitted when the `value` of `ion-input` is modified externally. `ionChange` is only emitted from user committed changes, such as typing in the input and the input losing focus or from clicking the clear action within the input.
diff --git a/core/src/components/datetime-button/datetime-button.tsx b/core/src/components/datetime-button/datetime-button.tsx
index 73f1e6ed46..3200b84ca9 100644
--- a/core/src/components/datetime-button/datetime-button.tsx
+++ b/core/src/components/datetime-button/datetime-button.tsx
@@ -204,11 +204,6 @@ export class DatetimeButton implements ComponentInterface {
const firstParsedDatetime = parsedDatetimes[0];
const use24Hour = is24Hour(locale, hourCycle);
- // TODO(FW-1865) - Remove once FW-1831 is fixed.
- parsedDatetimes.forEach((parsedDatetime) => {
- parsedDatetime.tzOffset = undefined;
- });
-
this.dateText = this.timeText = undefined;
switch (datetimePresentation) {
diff --git a/core/src/components/datetime/datetime-interface.ts b/core/src/components/datetime/datetime-interface.ts
index 83aa501af8..7071b28696 100644
--- a/core/src/components/datetime/datetime-interface.ts
+++ b/core/src/components/datetime/datetime-interface.ts
@@ -19,7 +19,6 @@ export interface DatetimeParts {
hour?: number;
minute?: number;
ampm?: 'am' | 'pm';
- tzOffset?: number;
}
export type DatetimePresentation = 'date-time' | 'time-date' | 'date' | 'time' | 'month' | 'year' | 'month-year';
diff --git a/core/src/components/datetime/datetime.tsx b/core/src/components/datetime/datetime.tsx
index 92ff2119d9..a3a40f8c6d 100644
--- a/core/src/components/datetime/datetime.tsx
+++ b/core/src/components/datetime/datetime.tsx
@@ -503,25 +503,6 @@ export class Datetime implements ComponentInterface {
if (activePartsIsArray && activeParts.length === 0) {
this.setValue(undefined);
} else {
- /**
- * Prevent convertDataToISO from doing any
- * kind of transformation based on timezone
- * This cancels out any change it attempts to make
- *
- * Important: Take the timezone offset based on
- * the date that is currently selected, otherwise
- * there can be 1 hr difference when dealing w/ DST
- */
- if (activePartsIsArray) {
- const dates = convertDataToISO(activeParts).map((str) => new Date(str));
- for (let i = 0; i < dates.length; i++) {
- activeParts[i].tzOffset = dates[i].getTimezoneOffset() * -1;
- }
- } else {
- const date = new Date(convertDataToISO(activeParts));
- activeParts.tzOffset = date.getTimezoneOffset() * -1;
- }
-
this.setValue(convertDataToISO(activeParts));
}
}
@@ -1211,7 +1192,7 @@ export class Datetime implements ComponentInterface {
*/
const singleValue = Array.isArray(valueToProcess) ? valueToProcess[0] : valueToProcess;
- const { month, day, year, hour, minute, tzOffset } = clampDate(singleValue, minParts, maxParts);
+ const { month, day, year, hour, minute } = clampDate(singleValue, minParts, maxParts);
const ampm = parseAmPm(hour!);
this.setWorkingParts({
@@ -1220,7 +1201,6 @@ export class Datetime implements ComponentInterface {
year,
hour,
minute,
- tzOffset,
ampm,
});
@@ -1240,7 +1220,6 @@ export class Datetime implements ComponentInterface {
year,
hour,
minute,
- tzOffset,
ampm,
};
}
diff --git a/core/src/components/datetime/test/basic/datetime.e2e.ts b/core/src/components/datetime/test/basic/datetime.e2e.ts
index 3d01593a56..bec68f39c7 100644
--- a/core/src/components/datetime/test/basic/datetime.e2e.ts
+++ b/core/src/components/datetime/test/basic/datetime.e2e.ts
@@ -99,11 +99,7 @@ test.describe('datetime: selecting a day', () => {
await ionChange.next();
- const value = await datetime.evaluate((el: HTMLIonDatetimeElement) => el.value);
- await expect(typeof value).toBe('string');
-
- // Check to make sure value includes current time
- await expect(value!.includes('2022-10-01T16:22')).toBe(true);
+ await expect(datetime).toHaveJSProperty('value', '2022-10-01T16:22:00');
});
});
@@ -134,6 +130,7 @@ test.describe('datetime: confirm date', () => {
`);
+ const ionChange = await page.spyOnEvent('ionChange');
const datetimeMonthDidChange = await page.spyOnEvent('datetimeMonthDidChange');
const eventButton = page.locator('button#bind');
await eventButton.click();
@@ -146,10 +143,9 @@ test.describe('datetime: confirm date', () => {
const datetime = page.locator('ion-datetime');
await datetime.evaluate((el: HTMLIonDatetimeElement) => el.confirm());
- // Value may include timezone information so we need to check
- // that the value at least includes the correct date/time info.
- const value = (await datetime.evaluate((el: HTMLIonDatetimeElement) => el.value))!;
- expect(value.includes('2021-12-25T12:40:00')).toBe(true);
+ await ionChange.next();
+
+ expect(datetime).toHaveJSProperty('value', '2021-12-25T12:40:00');
});
});
diff --git a/core/src/components/datetime/test/format.spec.ts b/core/src/components/datetime/test/format.spec.ts
index 74e81bf890..7db7254e8d 100644
--- a/core/src/components/datetime/test/format.spec.ts
+++ b/core/src/components/datetime/test/format.spec.ts
@@ -102,34 +102,6 @@ describe('getLocalizedDayPeriod', () => {
});
describe('getLocalizedTime', () => {
- describe('with a timezone offset', () => {
- it('should ignore the offset and localize the time to PM', () => {
- const datetimeParts = {
- day: 1,
- month: 1,
- year: 2022,
- hour: 13,
- minute: 40,
- tzOffset: -240,
- };
-
- expect(getLocalizedTime('en-US', datetimeParts, false)).toEqual('1:40 PM');
- });
-
- it('should ignore the offset and localize the time to AM', () => {
- const datetimeParts = {
- day: 1,
- month: 1,
- year: 2022,
- hour: 9,
- minute: 40,
- tzOffset: -240,
- };
-
- expect(getLocalizedTime('en-US', datetimeParts, false)).toEqual('9:40 AM');
- });
- });
-
it('should localize the time to PM', () => {
const datetimeParts = {
day: 1,
@@ -137,7 +109,6 @@ describe('getLocalizedTime', () => {
year: 2022,
hour: 13,
minute: 40,
- tzOffset: 0,
};
expect(getLocalizedTime('en-US', datetimeParts, false)).toEqual('1:40 PM');
@@ -150,7 +121,6 @@ describe('getLocalizedTime', () => {
year: 2022,
hour: 9,
minute: 40,
- tzOffset: 0,
};
expect(getLocalizedTime('en-US', datetimeParts, false)).toEqual('9:40 AM');
@@ -163,7 +133,6 @@ describe('getLocalizedTime', () => {
year: 2022,
hour: 0,
minute: 0,
- tzOffset: 0,
};
expect(getLocalizedTime('en-GB', datetimeParts, false)).toEqual('12:00 am');
diff --git a/core/src/components/datetime/test/minmax/datetime.e2e.ts b/core/src/components/datetime/test/minmax/datetime.e2e.ts
index 27e39281bb..71dfd209df 100644
--- a/core/src/components/datetime/test/minmax/datetime.e2e.ts
+++ b/core/src/components/datetime/test/minmax/datetime.e2e.ts
@@ -257,9 +257,7 @@ test.describe('datetime: minmax', () => {
await ionChange.next();
- const value = await datetime.evaluate((el: HTMLIonDatetimeElement) => el.value);
- await expect(typeof value).toBe('string');
- await expect(value!.includes('2022-10-10T08:00')).toBe(true);
+ await expect(datetime).toHaveJSProperty('value', '2022-10-10T08:00:00');
});
test('should reset to max time if out of bounds', async ({ page }) => {
await page.setContent(`
@@ -278,9 +276,7 @@ test.describe('datetime: minmax', () => {
await ionChange.next();
- const value = await datetime.evaluate((el: HTMLIonDatetimeElement) => el.value);
- await expect(typeof value).toBe('string');
- await expect(value!.includes('2022-10-10T08:00')).toBe(true);
+ await expect(datetime).toHaveJSProperty('value', '2022-10-10T08:00:00');
});
});
});
diff --git a/core/src/components/datetime/utils/format.ts b/core/src/components/datetime/utils/format.ts
index 53901f4a58..6a9b7d5724 100644
--- a/core/src/components/datetime/utils/format.ts
+++ b/core/src/components/datetime/utils/format.ts
@@ -18,21 +18,25 @@ export const getLocalizedTime = (locale: string, refParts: DatetimeParts, use24H
return new Intl.DateTimeFormat(locale, {
hour: 'numeric',
minute: 'numeric',
+ /**
+ * Setting the timeZone to UTC prevents
+ * new Intl.DatetimeFormat from subtracting
+ * the user's current timezone offset
+ * when formatting the time.
+ */
timeZone: 'UTC',
/**
* We use hourCycle here instead of hour12 due to:
* https://bugs.chromium.org/p/chromium/issues/detail?id=1347316&q=hour12&can=2
*/
hourCycle: use24Hour ? 'h23' : 'h12',
- }).format(
- new Date(
- convertDataToISO({
- ...refParts,
- // TODO: FW-1831 will remove the need to manually set the tzOffset to undefined
- tzOffset: undefined,
- })
- )
- );
+ /**
+ * Setting Z at the end indicates that this
+ * date string is in the UTC time zone. This
+ * prevents new Date from adding the time zone
+ * offset when getting the ISO string.
+ */
+ }).format(new Date(convertDataToISO(refParts) + 'Z'));
};
/**
diff --git a/core/src/components/datetime/utils/manipulation.ts b/core/src/components/datetime/utils/manipulation.ts
index 34ac4af7d4..af32a4a54c 100644
--- a/core/src/components/datetime/utils/manipulation.ts
+++ b/core/src/components/datetime/utils/manipulation.ts
@@ -36,18 +36,6 @@ export function convertDataToISO(data: DatetimeParts | DatetimeParts[]): string
if (data.hour !== undefined) {
// YYYY-MM-DDTHH:mm:SS
rtn += `T${twoDigit(data.hour)}:${twoDigit(data.minute)}:00`;
-
- if (data.tzOffset === undefined) {
- // YYYY-MM-DDTHH:mm:SSZ
- rtn += 'Z';
- } else {
- // YYYY-MM-DDTHH:mm:SS+/-HH:mm
- rtn +=
- (data.tzOffset > 0 ? '+' : '-') +
- twoDigit(Math.floor(Math.abs(data.tzOffset / 60))) +
- ':' +
- twoDigit(data.tzOffset % 60);
- }
}
}
}
diff --git a/core/src/components/datetime/utils/parse.ts b/core/src/components/datetime/utils/parse.ts
index 95c05b9be6..fda79085ac 100644
--- a/core/src/components/datetime/utils/parse.ts
+++ b/core/src/components/datetime/utils/parse.ts
@@ -93,20 +93,6 @@ export function parseDate(val: string | string[] | undefined | null): DatetimePa
parse[i] = parse[i] !== undefined ? parseInt(parse[i], 10) : undefined;
}
- let tzOffset = 0;
- if (parse[9] && parse[10]) {
- // hours
- tzOffset = parseInt(parse[10], 10) * 60;
- if (parse[11]) {
- // minutes
- tzOffset += parseInt(parse[11], 10);
- }
- if (parse[9] === '-') {
- // + or -
- tzOffset *= -1;
- }
- }
-
// can also get second and millisecond from parse[6] and parse[7] if needed
return {
year: parse[1],
@@ -114,7 +100,6 @@ export function parseDate(val: string | string[] | undefined | null): DatetimePa
day: parse[3],
hour: parse[4],
minute: parse[5],
- tzOffset,
ampm: parse[4] < 12 ? 'am' : 'pm',
};
}